Re: Roadmap Updated

"Charlie Poole" <[email protected]>
Newsgroups gmane.comp.windows.dotnet.nunit.devel
Message-ID <000001c8830b$d4b72370$6401a8c0@ferrari>
Hi Kelly, 

> The current approach seems to be that the test cases are 
> created at Load... time, and then are subsequently Run when 
> you select a test case to run.

Yes.. and in most cases, user code in the test assembly
does not participate in loading tests. The only exception
I can think of is the Suite property, which is required
to be static.

> One issue I'm having in using 
> IterativeTest is that the Load time can get unreasonably long 
> even in the case where I only want to run a single test. (It 
> also seems to occasionally gratuitously reload the tests, but 
> that's a side issue.) This seems to be the case whether I'm 
> using TestDriven.NET or the NUnit GUI, so I assume that this 
> must be a core issue, or at least both have chosen the same 
> implementation.

If tests are reloading without being told to reload, then I
would suspect your extension as being the culprit. :-)

However, there are many ways to "tell" the test to reload,
so check your NUnit options and turn off all automatic 
reloading while testing this.

> If, on the other hand, one could be lazy about test creation, 
> and only create the test when it's about to be run, that 
> would make for a more efficient system. (At least the way I'm 
> using it.) This might also be the case in general, it's just 
> more obvious for IterativeTest.

NUnit creates all "tests" at load time, but those tests are not
instances of the user test fixture class. An NUnitTestMethod
is fairly lightweight, but it does require a bit of reflection
in order to get all the properties of the test to match the
attributes you specify. Since the attributes on the method
don't change for each test case, you should check to see if
your implementation is repeating that reflection every time.
It's only needed once, but depending on your inheritance
hierarchy it could be happening more for each case.

> So, is there some way of being indeterminate until you either 
> try to expand the test in the NUnit GUI, or actually run the 
> test? Can we do lazy evaluation of the set of tests?

I'll deal with each option separately:

The Gui is completely decoupled from the test loader, which
is as it should be. The gui doesn't even have tests, just
the names of tests and other info about them. Of course,
we could have the gui drive the progressive loading of tests,
but that would not be a very clean architecture.

There is a possibility of having a test that dynamically
creates its own children when it is run. That would mean
the gui would be receiving notifications about tests that
it doesn't know about and would have to figure out where
to put them in the tree. I think we may need this at some
point, but it's much more complicated than the alternative
of using multiple result sets. I'd like to try the simpler
alternative first.

Here's what I mean by multiple result sets... Let's say
I have a method that tests multiplication. I want to 
run it with 2x2=4 0x7=0 90x1=90 as cases.

I can consider this as three tests, listed in the gui
tree as Multiply(2,2), Multiply(0,7) and Multiply(90,1).
That's how RowTest would do it, for example.

On the other hand, we can think about this as a single
TestMethod producing multiple results. The test tree
would list a single Multiply test. After execution,
the results would be placed in the tree under the test.
They would look pretty much like the tests in the first
approach - it's just a matter of how we think about it.

One advantage of this is that a TestResult is a 
very lightweight, serializable object. It has no
existence in the tree of tests created by the loader,
which is BTW different from the tree in the Gui, so
it doesn't have to be known in advance.

So that's an approach I plan to follow up on.

> It seems that you could get the name of the test from the 
> metadata without actually creating the test from calling 
> BuildFrom. Would that constitute an improvement in your 
> opinion to the current approach?
> This question is independent of 2.5 vs 3.0... although the 
> answer might not be.

If we are ready to call BuildFrom, what would we do instead
in order to defer it? First, we would have to know that
this is the type of test that needs to be deferred, but
we wouldn't know that until we built it.

Of course, the builder extension could simply save the
data and only build the subtests at the time it needed them,
but this has a few problems:

1) By that time, we have already done most of the work,
unless we are talking about very large sets of data.

2) A testcase is not a very big object anyway, so it
isn't clear we would make a net savings by caching
the info needed to create one and building it later.

> The best answer would seem to me to be that you could have 
> all the test names show up, and those that are Expandable (a 
> bool property?) would show potential expansion. Then when you 
> choose to expand it, A function is called that enumerates the 
> tests, finally, when you choose to execute a test, then 
> another function is called to prepare to run the test, 
> finally the test is run. If we could do lazy evaluation for 
> each of these steps, that would seem to be a huge improvement 
> over the current approach, at least in the cases I'm dealing with.
> 
> I'm a big fan of lazy evaluation.

Except that the entire NUnit approach to loading tests is already
based on lazy evaluation. NUnit only creates lightweight objects
that contain enough info to create your test fixture object and
invoke the tests when needed. I'm suspicious that you may be
doing something to defeat this in your extension - I'll try
to find time to look over the code.

> >  > The Theory syntax seems to merge these two approaches... 
> so  > I'm 
> > not sure whether or not it remains an unsolvable problem  > 
> to merge 
> > the two approaches.
> >
> >  No - the Theory examples we have seen use both approaches. 
> So  NUnit 
> > would need to support both of them... unless that's what  
> you mean by 
> > merge. :-)
> 
> Yes, that's what I mean. Internally this requires two 
> different approaches, of course.

And to repeat the point Andreas was making, we would like
each extension that uses data to be able to use any data
providers interchangeably. Just as Theory does.

> >  > The conversation you pointed to was technically a little 
> past  > my 
> > experience thus far (too internal), so while I'm very  > 
> interested, I 
> > couldn't make a helpful reply.
> >
> >  That's cool. Jump in where you can. We're at the implementation  
> > stage, where it's a question of how the internals will 
> work, so  it's 
> > natural that we're getting more technical. One way to read  
> this is to 
> > ask how the availabilitiy of some NUnit feature or  interface would 
> > help you to implement a given extension syntax.
> 
> I'm not especially dense, but I am unfamiliar with most of 
> the NUnit internals. I feel most comfortable and useful at 
> this point looking at things from the user's point of view. 
> By user, I mean both a general user as well as someone 
> writing extensions. I am not against getting my hands dirty 
> as might be helpful. I just recognize that there is ramp up 
> time involved to get to that point.

Bear in mind, for better or worse, NUnit extensibility has
never been targeted at the general user.  In fact, that is
a valid criticism some people have made. So, you do need
to get into certain internals - SimpleTestRunner and everything
it calls - to work effectively. But it's just code. :-)

Charlie

> -Kelly
> 
> --------------------------------------------------------------
> -----------
> This SF.net email is sponsored by: Microsoft Defy all 
> challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> nunit-developer mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/nunit-developer
> 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.