Initialising when an Assembly loads

P

Peter Gummer

I want to perform some initialisation when an assembly is first loaded.

I know about static constructors, but that's not what I want. A class's
static constructor is not called until something uses the class at run
time. That may be too late.

What I'm actually trying to do is hook up a TraceListener so that calls
to Debug.Assert will throw an exception inside NUnit unit tests.
Because the DefaultTraceListener just pops up a dialog within the NUnit
GUI (which interrupts the unit tests), or else writes to the output
when run without a GUI (e.g. within the TestDriven.NET add-in), the
unit test in which the assertion failed is wrongly flagged as having
succeeded. NUnit needs an exception. I intend to supply that exception
by writing a TraceListener that will be hooked up by my unit tests. I
could hook it up in, say, the SetUp of my unit tests, or in their
static constructor, but what if I forget to do so for one of my test
fixture classes? I would rather do it once and for all on loading the
assembly that contains my unit tests.

But I can't figure out how!

Thanks,
Peter Gummer
 
P

Peter Gummer

Truong said:
How about configuring your listener in app.config?

Nice idea, except that it's not my application that I want to do this
to, it's my applications unit tests. They are executed by some other
app, e.g. the NUnit GUI app.

I guess I could edit the NUnit GUI's config. But most of the time I use
the TestDriven.NET Visual Studio add-in. I wonder what config file I'd
have to edit to make that use my listener.

I think the ideal solution would be if there were an answer to my
original question, i.e. by performing the initialisation on loading the
unit test assembly.

- Peter Gummer
 
P

Peter Gummer

Stephen said:
How about AppDomain.AssemblyLoad ?

Hi Stephen!

Yes, it would be good to set up my TraceListener when that event is
fired. But where would I set up my AssemblyLoadEventHandler? It's the
same problem as for my TraceListener.

I have no "Main". Well, the NUnit GUI has a Main, but I don't want to
go editing that. Anyway, doing so still wouldn't solve the problem for
other things that might run my unit tests, such as TestDriven.NET.

What I really need is something comparable to Delphi's unit
"initialization" section: a decentralised bit of code that is
guaranteed to be run on load. C# seems to have no such thing.

There's no magic way to do this with AssemblyInfo.cs, is there?

-- Peter Gummer
 
S

Stephen Ahn

Peter,

Hmm, somehow i didn't think the solution would be that easy (otherwise one
of you guys would have worked it out already :)
Good luck, i hope everyone is doing well over there !

Stephen
 
T

Truong Hong Thi

Hi Peter,

I think Debug.Assert is more suitable for debugging than for unit
testing purpose.
So I think you don't need to try to convert a Debug.Assert into an
exception. If the exception makes sense, why not throw it instead of
using Debug.Assert?

I think if you wrote complete unit test suite which cover the cases
that Debug.Assert is used, then such an exception cannot escape.

I think unit test should yield the same results when run with either
debug or release builds.

Regards,
Thi - http://thith.blogspot.com
 
P

Peter Gummer

Truong said:
So I think you don't need to try to convert a Debug.Assert into an
exception. If the exception makes sense, why not throw it instead of
using Debug.Assert?

Because I'm using Debug.Assert to detect programming errors, in the
manner of Design by Contract. Hopefully these errors will be eradicated
before releasing the product. Debug.Assert has no runtime overhead for
release builds.

So, in a debug build, the failure of a Debug.Assert is a bug. If it
happens to fail in a unit test then I want to know about it. NUnit
detects failures via exceptions. I don't think there's any way to
configure NUnit to detect Debug.Assert failures too. It might be nice
to allow it to keep running, as it would in a release build, as long as
NUnit can detect that it failed and report as much, instead of wrongly
saying the test passed. Doing that would require a hook into NUnit that
I think NUnit just doesn't have.

Regardless of whether I throw an exception or somehow find a way to
tell NUnit that it failed without throwing an exception, I still need
to set up my own TraceListener.

So my original question remains. Is there a way for C# to let me hook
up a TraceListener on assembly load? A static constructor nearly does
what I want, but it may be too late; and I don't have a Main routine
that I can depend on.

Anyway, I've posted a message to the NUnit forum on SourceForge, so I
may get a solution there.

-- Peter Gummer
 
T

Truong Hong Thi

OK, Peter, do whatever you think is right.
I guess you could write a base class for all of your test fixture, and
put your initialization in either setup method or constructor. To
prevent your listener being added multiple times, you might need to
check for its existence before adding.
Regards,
Thi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top