[MonoDevelop] First go at unit tests

Lluis Sanchez lluis at ximian.com
Sat Dec 3 08:25:48 EST 2005

> On 12/2/05, Lluis Sanchez <lluis at ximian.com> wrote:
>         Hi,
>         > Ok, I tried testing the SourceViewTextIterator class in
>         > SourceEditorDisplayBinding.cs. The class is private and this
>         turned
>         > out to be quite problematic. I had to start up a lot of MD
>         > infrastructure in the test to even get this class
>         instantiated. This 
>         > is a bad smell IMO.
>         That was expected.
> Well, for this particular class maybe it was. But I am sure it is easy
> to unit test a lot of other code this way.

Core assemblies which are not related to the IDE can be probably tested
in this way. There may also be other classes in MonoDevelop.Ide that can
be easily tested. But in general most of classes rely on a properly
initalized infrastructure, and you'll find the same problems with those.

>         >
>         > I do not think it is feasible to do it this way. So how do I
>         go about 
>         > testing this class? I see a couple of options:
>         >
>         > * Put the test in the class.

First of all, I don't like the idea of fatting up the assemblies with
code that is not needed at runtime. Although yes, you can use
conditional compilation for this.

But the main reason is that it won't help in building up a test
framework for Monodevelop. Your test would only be testing a particular
implementation of the search engine, not the *MonoDevelop* search
engine. If that is what you want to do, ok, but I don't think it is the
correct path.

If we next month decide to drop the GtkSourceView based editor and
implement our own manged editor, all those tests will be useless, and
we'll have nothing to ensure that the new editor does the search in the
same way as the old did, and that there are not regressions.

>         > * Make the class public.

Making a class public is a very serious decision. You are adding the
class to the public API, which means that users of that library may use
that class, so you can't change it without breaking the binary

So, if you make public an internal implementation class, it means that
changing the internal implementation might break assembly compatibility.
And that's really bad.

>         > * Move the class somewhere else.

I don't see how this can help. If you move the class to another assembly
you'll have to make it public so the original assembly can use it, and
you'll have yet another assembly dependency.

>         None of those options are acceptable.
> Could you elaborate on that, please? 
>         >
>         > It ought not be so hard to unit test a search algorithm.
>         Maybe the
>         > algorithm should be moved somewhere else?
>         >
>         > Any good ideas out there? :-)
>         I think that the best solution would be to implement a Tester
>         add-in,
>         which once loaded in MD would use the public API to test
>         whatever needs 
>         to be tested.
>         You would not directly test the SourceViewTextIterator class,
>         but
>         instead you would use the MonoDevelop.Ide.Gui.Search api,
>         which
>         internaly relies on that class.
> I am not very fond of this approach. First of all I would like to run
> by tests as part of the build process. I would not like to have to
> start MonoDevelop to be able to run my unit tests.

I already said it many times, but here is it again: many of the
MonoDevelop classes won't work without a properly initialized
MonoDevelop runtime. So you must 'start' MonoDevelop to unit test them.
It doesn't mean that you have to do it manually, and I don't see the
reason why it could not be part of the build.

>  Secondly it might be hard to test the internals of a class using only
> some public API.

Mono has around 13000 unit tests, all of them using exclusively public
API, so it's not so hard...

> /Jacob
>         Lluis.

More information about the Monodevelop-list mailing list