[MonoDevelop] First go at unit tests

Lluis Sanchez lluis at ximian.com
Mon Dec 5 17:02:20 EST 2005

Hi Jacob,

>         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.
> That is actually what I wanted to do. Test a particular implementation
> with a unit test.
> And we then know that *MonoDevelop* search works if all the particular
> implementations are tested individually.

I rather prefer one single test for all implementations, which defines
the expected common behavior.

>         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.
>  It is true that they will be useless but that argument goes for all
> code that is thrown away.
> But as long as we use the GtkSourceView based editor they will not be
> useless.

If we write a test for the search engine, we don't need to throw it away
if we change a particular implementation. We are reusing the test and
making sure that everithing keeps working in the same way.

If we change the search engine, we need to throw away that test, of
course. But at least we would need to write only one new test, not one
for every implementation. That's a big win.

>         >         > * 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
>         compatiblity.
>         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.
> I agree, it is also the option I like the least.
>         >         > * 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.
> The reason I added this option was that I did not think the search
> algorithm belonged in a GUI class.
> So moving it to another class that was not so bound to the GUI might
> make it easier to test.

The MonoDevelop search algorithm is already independent from the GUI.
The algorithm is implemented in the DefaultFind class, in the
MonoDevelop.Ide.Gui.Search namespace (which has Gui in the name, but
this specific class has no GUI dependencies). This algorith uses a
combination of ISearchStrategy, IDocumentIterator and ITextIterator to
find text.

Some months ago I added a SearchNext() method in ITextIterator. The goal
of this method was to improve the performance of the search operation.
The problem was that the generic implementation of the search algorithm
was much slower than the native search method provided by GtkSourceView.

So, right now an ITextIterator implementation can provide native search
support through this method, and the main search algorithm will use it
if it can. It won't be always possible, since the MonoDevelop search
engine provides more search options than what GtkSourceView can provide
(for example, native search won't be used when looking for 'whole
word'). The search engine calls ITextIterator.SupportsSearch to find out
if the native search can be used for a particular search operation.

Of course, all this is completely transparent to the user of the search
engine API.

In summary, SourceViewTextIterator.SearchNext is a fast path
implementation of the search algorithm, and it certainly needs to belong
to a GUI class and depend on GtkSourceView.

>         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.
> Ok, so if I made some Test AddIn, I would like something like make
> test to do something like this:
> 1. Build the test AddIn and copy it to the AddIn directory.
> 2. Launch MonoDevelop.
> 3. Execute the code in the Test AddIn.
> 4. Quit MonoDevelop.
> Is this possible to do automatically? I am thinking of step 3.

Yes, all this can be done. Add-ins can define auto-start commands that
are executed at MD startup. The only issue to be solved would be how to
decide wether to run the tests or not, since if the addin is copied to
the addins dir it will always be loaded, even when not wanting to run
the test suite.

>         >  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...
> Nope, it's not hard, we just need to find the right way to do it. :-) 
>         >
>         > /Jacob
>         >
>         >
>         >         Lluis.
>         >
>         >
>         > 
>         _______________________________________________
>         Monodevelop-list mailing list
>         Monodevelop-list at lists.ximian.com
>         http://lists.ximian.com/mailman/listinfo/monodevelop-list

More information about the Monodevelop-list mailing list