Nice learning curve :-) Of course NUnit is a much easier climb than WPF...
> I know how to create a NUnit test for VB.NET.
> However, I'm having difficulty trying to create an NUnit test for some
> WPF Xaml code.
The problem here may be that XAML is primarily declarative in nature
and that NUnit is primarily for testing procedural code. Using NUnit
to test declarative code is fairly new in it's bag of tricks, and
nobody has really stretched it in the direction of testing XAML. There
is an XML Test out there, but I haven't had a lot of experience with
it. Essentially, as I understand, it used XPaths to assert that the
produced XML had certain elements in it.
NUnit has some new data driven testing features in the newer betas of
2.5 that could potentially be helpful. I wish I had better ideas about
how to develop WPF code using TDD, but I don't. The problem in my
opinion is that TDD exists primarily to test code, not data. WPF's
XAML is primarily data, not really code. So that leaves us in a space
where what is needed is some creative approaches to a difficult
problem.
> I need to be able to set up some NUnit test for chunks of Xaml code.
> I was thinking about adding a chunk of Xaml code that I want to test
> in NUnit and then using
> an Assert.AreEqual to verify that the Xaml code executed is equal to
> the Xaml code chunk
> I added to the test.
I think there are some functions in the new NUnit for comparing chunks
of XML, but I can't remember if they actually made it in, or were just
a point of discussion.
> Is there a post somewhere that has some code examples for this?
No. There is not. It's hard enough to test GUIs when they are
procedural. Testing declarative GUI code is essentially a research
topic. Any aspiring PhD candidates out there?
-Kelly
Hi Rita,
This may sound like a bit of a cop out, because it is. However, what
I have traditionally done in such situations is to separate my code
out into testable code, and GUI code. The idea being to extract into a
testable situation as much of the functionality as possible, leaving
the GUI so utterly simplistic that it cannot possibly fail (yeah
right, I hear you say).
So, given your example, I would create a testable C# class that
processes the business rules for how the string (obtained from the
text box) is translated into the show/hide/contents/etc. of the other
parts of the GUI. I then have the GUI simply show the current state
from this object (which is a bit like the get/set pairs that people so
often say they don't test either).
Now, I admitted that this was a cop out. I do believe there is
something we can do to text the XAML code itself, we just haven't
quite thought of it yet. I think it's possible, it's kind of like on
the tip of my tongue, but I just can't quite get it out yet. I think
if I worked with XAML for a few months, I would likely figure it out,
or at least come up with some useful ideas, but I haven't had the
chance yet.
For now, my best advise is separate concerns, keep the GUI as
simplistic as possible, and test the heck out of everything else. I'm
sorry if that's not really an answer to your question (I admit that it
isn't) but it is the state of the art insofar as I've been able to
discern it.
The vague idea that I have is to essentially implement the XAML
twice, in two different ways (one perhaps more visual than the other),
and assert that both ways end up doing the same thing. I told you it
was vague. :-) The key analogy is double entry book keeping. If you
can enter the information twice, in a way that can be verified against
the other way, then you are likely to get things right. How to do
double entry book keeping of XML, is, as I said previously a topic for
research. I think it's a target rich environment... again fishing for
graduate students to think about this more... :-) I believe that you
can only test declarative code with more declarative code. Testing
declarative code against procedural code is a mismatch that I don't
think will work. So, if you could somehow declare that if x, y and z,
then text "foo" should show up... then that's the sort of thing that
feels like it might work.
There were some discussions on the Yahoo TDD list a while back on
this... you might look at the archives. Good luck.
-Kelly
> Thanks for your interest.
>
> What I'm trying to accomplish is to create a NUnit test for
> some Xaml code.
> One set of Xmal code may represent a main rectangle with
> several smaller rectangles within it.
> This main rectangle also has a couple of labels whose Content
> value changes according to the value of a TextBox's single character.
> The main Rectangle's color will also change and the inner
> rectangles will be visible depending on this value also.
>
> So, I need to be able to create an NUnit test that passes in
> a single character (A-Z) and then verifies that the graphic
> produced by the Xaml code executed is what I'm expecting it
> to be. For this rectangle example I created a User Control.
>
> Hope that clarifies it for you.
Although xaml testing is new to all of us, there is a large
body of knowledge and experience at general Gui testing,
including Windows Forms, Java, etc.
Usually one does not test what is displayed because that would
be a test of the platform - of Windows for example. Rather, one
tests that the platform is given the correct thing to display.
For example, in testing a textbox, we want to ensure that it
contains the proper text. We don't test that it /displays/
that text, because we trust Windows to do it for us.
So, when you speak of testing that the "graphic displayed by
the Xaml code" is what you expect it to be, I read that as
trying to test how Xaml works, not how your application works.
Is that what you mean? If it were me, I would be testing the
Wpf gui in just the same way as I test a Windows forms Gui -
by verifying that properties of the display elements are
set correctly.
Charlie
While there is a lot of knowledge about testing GUIs out there, I
think it is fair to acknowledge that it is deemed more difficult than
testing general purpose code. A lot of people don't test the GUI as
much as the rest of the application even amongst true TDD acolytes
because its hard, and because you'll probably see any major problems
running the program. Rigorous Separation of Concerns so that the GUI
has ONLY GUI code in it is the best advise going for most programmers
doing TDD IMHO.
> Usually one does not test what is displayed because that would
> be a test of the platform - of Windows for example. Rather, one
> tests that the platform is given the correct thing to display.
> For example, in testing a textbox, we want to ensure that it
> contains the proper text. We don't test that it /displays/
> that text, because we trust Windows to do it for us.
I agree with this part very much.
> So, when you speak of testing that the "graphic displayed by
> the Xaml code" is what you expect it to be, I read that as
> trying to test how Xaml works, not how your application works.
And I agree that you don't want to test XAML's behavior.
> Is that what you mean? If it were me, I would be testing the
> Wpf gui in just the same way as I test a Windows forms Gui -
> by verifying that properties of the display elements are
> set correctly.
Because XAML is declarative and Windows Forms are primarily procedural
(with some declarative elements) I think there is a significant
difference worth noting. Much of what you can do to test Windows Forms
can be transitioned over to WPF testing, and some of it will have to
be adapted to a very different way of looking at GUIs in general. One
of the reasons that I've pushed for data driven tests so much over the
last year is that I think it pushes us in the direction of being able
to more easily test XAML GUIs... time and experience will tell us if
it is sufficient, or if we need to take further steps.
-Kelly
I'm going to have to catch that sometime then ;-)
> Of course it's
> hard, but so are a lot of things we do. At bottom, it's
> just another exercise at separation of concerns and
> isolation of what we need to test.
A lot of us test what is easy to test, and sometimes skip testing the
things that are really hard to test. I guess it's the old thing about
whether the sabbath is for man or man for the sabbath. I think TDD is
for the programmer, not vice versa.
That being said, if testing GUIs were easier, there would sure be a
lot of benefit from doing so.
>> A lot of
>> people don't test the GUI as much as the rest of the
>> application even amongst true TDD acolytes because its hard,
>> and because you'll probably see any major problems running
>> the program. Rigorous Separation of Concerns so that the GUI
>> has ONLY GUI code in it is the best advise going for most
>> programmers doing TDD IMHO.
>
> Good advice.
Thanks.
>> Because XAML is declarative and Windows Forms are primarily
>> procedural (with some declarative elements) I think there is
>> a significant difference worth noting. Much of what you can
>> do to test Windows Forms can be transitioned over to WPF
>> testing, and some of it will have to be adapted to a very
>> different way of looking at GUIs in general. One of the
>> reasons that I've pushed for data driven tests so much over
>> the last year is that I think it pushes us in the direction
>> of being able to more easily test XAML GUIs... time and
>> experience will tell us if it is sufficient, or if we need to
>> take further steps.
>
> Although Xaml is declarative, Wpf can be programmed without
> Xaml - Petzold style, if you will. Not that I suggest you
> write apps that way, but you may need to write tests - or
> even better a test framework - in that way.
Writing WPF code without using the declarative coding techniques is a
lot like using your desk top computer as a calculator. Yes, it works,
but you're not taking advantage of much of the power at your
fingertips.
To see some of the coolest WPF apps yet, I would recommend going to
www.ted.com and watching the two talks by Jonathan Harris on story
telling. Very cool stuff there.
-Kelly
> > Although Xaml is declarative, Wpf can be programmed without Xaml -
> > Petzold style, if you will. Not that I suggest you write apps that
> > way, but you may need to write tests - or even better a
> test framework
> > - in that way.
>
> Writing WPF code without using the declarative coding
> techniques is a lot like using your desk top computer as a
> calculator. Yes, it works, but you're not taking advantage of
> much of the power at your fingertips.
Sure. But you could say something similar about Reflection.
It's really not a very efficient way to call methods. It's
much better to take advantage of the compiler to call
metods directly.
However, NUnit could not be written without using reflection
to call your tests. Sometimes tools have to use lower-level
approaches than one would use in a regular application.
I'm pretty sure that a test framework or plugin for testing
WPF will have to access WPF programatically.
Charlie
I'm not talking about efficiency of the machine, but of the
programmer. I think we've long gotten past the days of programmers
working for days on end to squeeze that last machine cycle out of the
inner most loop (for most applications).
> However, NUnit could not be written without using reflection
> to call your tests. Sometimes tools have to use lower-level
> approaches than one would use in a regular application.
Big fan of reflection here... also of declarative programming. So
you're preaching to the choir.
> I'm pretty sure that a test framework or plugin for testing
> WPF will have to access WPF programatically.
Maybe. But I think the best solution for testing a declarative user
interface will likely also be declarative. I don't have anything
concrete, but my gut tells me that the difficulties of the impedance
mismatch between the declarative style and the procedural style will
make the testing of declarative GUIs using procedural coding styles
less efficient theoretically.
Imagine, for example, a testing mechanism that lets you draw with a
drawing tool what the GUI should look like under certain declared
circumstances for certain declared data values... and then an
automatic system that tests that against the declarative XAML code.
That seems like double entry bookkeeping. Doing declarative on one
side and procedural on the other would be a bit like doing double
entry bookkeeping with dollars on one side and euros on the other.
While I see that it could be accomplished, it seems more difficult
than might theoretically be necessary.
Now, what I'm talking about is totally theoretical and vaporware.
There would be a huge amount of effort necessary to make it work, and
to make it maintainable. I think it would make a great PhD or Master's
thesis. I don't think it's a bigger problem than that, which is good
news for some poor graduate student fishing around for ideas.
-Kelly
> One way you can do this is to use the XamlLoader class to
> parse the chunk of Xaml you want to test. Once you have it
> loaded you can access it programmatically. In the test you
> change the value of the text box and then check that
> properties, etc of the rectangles have responded in the way you want.
This is reminiscent of the discussion Kelly and I were having about
testing WPF - programmatic versus declarative approaches.
Charlie