Unit Testing ASP.NET

  • Thread starter Thread starter Unit Test ASP.NET WebForm
  • Start date Start date
U

Unit Test ASP.NET WebForm

Alright, so I'm trying to do the right thing and bring the concept of Unit
Testing into our ASP.NET Web Application, but we're running into walls left
and right. The biggest challenge we're facing right now involves unit
testing a .ASPX page where the assertion needs to evaluate a property of a
..ASCX user control included on this page. My thought was that we could
construct a PrivateObject the same way we do for a ASPX and be able to use
the po.GetProperty method to retrieve a property value at run-time for the
user control to test the assertion. However, we receive the
System.MissingMethodException exception when attempting to access this
property that is defined in the code-behind of the .ASCX control. Is it
possible to accomplish what I am trying or is some other method necessary?

Here is an example of the Test Method code:

<TestMethod()> _
<HostType("ASP.NET")> _
<UrlToTest("http://localhost/test/MyProspectsDetail.aspx")> _
<AspNetDevelopmentServerHost("C:\Projects\Test\Source", "/test")> _
Public Sub MyTest()
'System.Diagnostics.Debugger.Break()
Dim p As Page = TestContext.RequestedPage
Dim po As PrivateObject = New PrivateObject(p)
Dim mnu As UserControl =
p.Master.FindControl("cphSFA").FindControl("PageMenu")
Dim pp As PrivateObject = New PrivateObject(mnu)
pp.GetProperty("ItemEnabled", New Object())
'Additional code would normally follow here, but the exception is
encountered above and additional code wouldn't be reached, anyway. Also, no
assignment coded above intentionally to point out the exception, otherwise
the variable would just receive a value of "Nothing".
Assert.IsFalse(True, "Test")

End Sub

Any thoughts?
 
UI is damned near impossible to unit test. There are tools to reduce the
pain, but the fact you are mixing tags with code makes it very difficult. If
you truly want to unit test UI, try ASP.NET MVC, as it gives you better
tools. For web testing, the project type does not matter, so you can do it
on any web project. Visual Studio Team has the web testing. There are open
source web testing tools.

Another option, or an option you can also use WITH web testing, is move as
much code out of the web project as possible, so web testing becomes an
integration test and your functional code can be fully tested with unit
tests. This would be the direction I would head, as things that require
input end up testing more than the unit anyway (ie, UI testing), so the
concept of a unit test on a web UI is rather worthless. Integration and user
acceptance testing are different things.

One nice framework, for automated user acceptance testing, is the Fit
Framework. You should also look at FitNesse. They are not .NET specific, but
very useful for running a wide variety of UI cases.

Hope this helps!

--
Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

************************************************
| Think outside the box! |
************************************************

"Unit Test ASP.NET WebForm" <Unit Test ASP.NET
(e-mail address removed)> wrote in message
 
Unit said:
Alright, so I'm trying to do the right thing and bring the concept of Unit
Testing into our ASP.NET Web Application, but we're running into walls left
and right. The biggest challenge we're facing right now involves unit
testing a .ASPX page where the assertion needs to evaluate a property of a
.ASCX user control included on this page. My thought was that we could
construct a PrivateObject the same way we do for a ASPX and be able to use
the po.GetProperty method to retrieve a property value at run-time for the
user control to test the assertion. However, we receive the
System.MissingMethodException exception when attempting to access this
property that is defined in the code-behind of the .ASCX control. Is it
possible to accomplish what I am trying or is some other method necessary?

Here is an example of the Test Method code:

<TestMethod()> _
<HostType("ASP.NET")> _
<UrlToTest("http://localhost/test/MyProspectsDetail.aspx")> _
<AspNetDevelopmentServerHost("C:\Projects\Test\Source", "/test")> _
Public Sub MyTest()
'System.Diagnostics.Debugger.Break()
Dim p As Page = TestContext.RequestedPage
Dim po As PrivateObject = New PrivateObject(p)
Dim mnu As UserControl =
p.Master.FindControl("cphSFA").FindControl("PageMenu")
Dim pp As PrivateObject = New PrivateObject(mnu)
pp.GetProperty("ItemEnabled", New Object())
'Additional code would normally follow here, but the exception is
encountered above and additional code wouldn't be reached, anyway. Also, no
assignment coded above intentionally to point out the exception, otherwise
the variable would just receive a value of "Nothing".
Assert.IsFalse(True, "Test")

End Sub

Any thoughts?

You should understand what is a unit test and what is a functional test,
as I don't think you're doing a unit test.

http://www.cs.usfca.edu/~parrt/course/601/lectures/junit.html

<copied>
What is a unit test versus a functional test? A unit test is usually a
test on a method not on the overall functionality of a tool or
application. For example, testing a method that returns large prime
numbers is a unit test but testing the overall encryption algorithm that
uses that method is a functional test.
<end copy>

Here is some additional information about a when a unit test is not a
unit test, but rather it's a functional test.

http://haacked.com/archive/2008/07/22/unit-test-boundaries.aspx

In addition to this, a Web page should be as dumb as possible whereas
the Web controls are not addressed by the codebehind file directly. But
rather, the controls are passed and returned on an interface/view of a
presenter, like the presenter/view of a Model View Presenter pattern.

It's the presenter's job to get data from or set data in form controls,
which makes it much simpler to unit test, because you're testing against
interfaces and methods of the presenter.
 
"Unit Test ASP.NET WebForm" <Unit Test ASP.NET
(e-mail address removed)> wrote in message
Alright, so I'm trying to do the right thing and bring the concept of Unit
Testing into our ASP.NET Web Application, but we're running into walls
left
Any thoughts?
Well my first thought is about "do the right thing".
You see people were developing for years without automated testing and
managing to test their applications as they developed.
In fact we called it unit testing, but it involved the developer or another
developer.
Set that aside for a moment.
Then there is the fact that you seem to have a mature project.
Introducing unit testing into a mature project is a bad ide IMO.
You will find it is a huge overhead for little gain.
Well, unless your project is chock full of bugs and your devs prone to
changing things willy nilly.
The time to adopt unit testing is at the start of a project.
If you need it then you want to consider MVC or MVP.
 
Mr. Arnold, I appreciate you taking the time to read and respond to my
question. However, I don't believe a lecture on unit test versus functional
test serves any benefit to the specific question asked here.

The .ASPX in this case has logic responsible for identifying if a particular
user has permission to perform a specific action. Our attempt at a unit test
was to pass in a certain condition (a specific user) then execute the private
Sub that is responsible for enabling/disabling a control (that is within the
user control) and finally evaluate that that operation enabled or disabled
the user control's menu option correctly.

In my opinion, it is very sensible to have ASPX code behind responsible for
setting properties of controls based on business logic that only exists
within that page. Given what Microsoft has already provided in the
UnitTesting framework I was asking if it was possible to leverage its members
to access UserControls within the ASPX much like we can access the members of
the page itself.

The intent was to write and evaluate a very simple test. This test only
touches one very specific function of the ASPX and in that sense I refer to
it as a "Unit Test". What this type of "Test" should actually be called is
academic in my opinion. My question was simply given the tools available is
the below scenario intended to be possible and if so what are ways to
accomplish it. From other responses I am getting the impression that this is
currently not possible or extremely over complicated outside of MVC.
Fortunately, if somebody comes to this thread in the future wanting to know
the definition of "Unit Test" versus "Functional Test" they may also be
helped. Thanks for your contribution.

Thanks,
-Rudy
 
Thanks Andy,

Yes, the idea of leveraging automated tests to perform some of the routine
and mundane actions we pay people to do every month likely came too late. In
my group, and I would suspect many groups in the IT world, we spend 300+
man-hours to test simple functionalities in our web application as part of
each release. Based on some of the simple things we do it seemed so likely
that Unit Tests could perform some or most of these evaluations for us thus
leaving different more complex evaluations to be performed by humans.

The UnitTesting framework in .NET 3.5 comes so close to providing exactly
what we needed for our ASP.NET project, and I was hoping I was just missing
one small piece of the puzzle. Perhaps "Unit Tests" or whatever people want
to call them are not the right solution for this problem, but I can't be the
only developer on an IT team facing these challenges. Automated tests should
be able to be written to perform simple validations against web forms to
ensure future changes by other developers don't break existing functionality.
It's an interesting discussion to see how other ASP.NET shops EFFICIENTLY
handle this scenario if not via Unit Tests.

Again, thanks for your comments and opinion. It's too late for us to go MVC
or MVP with this project, so I'll either abandon the benefits of adopting
Unit Tests or find another solution (perhaps the Web Testing functionality of
Visual Team Studio). Worst case scenario we'll just keep doing what we have
been doing for years...

:(

-Rudy
 
Thanks Gregory,

I will look into what is available via Web Testing in Visual Studio Team
Edition. Hopefully, there are some tools within that product that help us
better manage our testing needs based on our unique requirements.

I would still love to hear from somebody familiar with the UnitTesting
framework in .NET 3.5 and specifically why a Unit Test can dive into a ASPX
partial class and perform actions, but you cannot get a PrivateObject to
construct itself within a UserControl and at runtime use the same reflection
methods (GetProperty,SetProperty, Invoke, etc) to access its members.

Thanks again,
-Rudy

P.S. I have no idea why MSDN is using "Unit Test ASP.NET WebForm" as my
username in these posts. Sorry...
 
Unit said:
Mr. Arnold, I appreciate you taking the time to read and respond to my
question. However, I don't believe a lecture on unit test versus functional
test serves any benefit to the specific question asked here.

It does serve a benefit as one needs to know and understand which one
needs to be used. And most developers don't know, which produces the
mistake you are making in so called Unit Testing.
The .ASPX in this case has logic responsible for identifying if a particular
user has permission to perform a specific action.

And that is a poor Web page or Web application UI design, where the Web
page and the codebehind file has business rules in it.
Our attempt at a unit test
was to pass in a certain condition (a specific user) then execute the private
Sub that is responsible for enabling/disabling a control (that is within the
user control) and finally evaluate that that operation enabled or disabled
the user control's menu option correctly.

And controls and all can be passed to a Model View Presenter through the
IView of the presenter with object injection into the presenter using
like methods in the presenter.

You can disable and enable controls. You can load the controls and read
data in the controls, doing a get passing the control and manipulating
the control anyway you need and giving the control back to the page from
the presenter. Because after all, the control is an 'object'.

And you Unit Test the presenter for expected behavior and not functional
test a page. If you're going to functional test a page, you might as
well set debug break points and visually watch on it in single step.

In my opinion, it is very sensible to have ASPX code behind responsible for
setting properties of controls based on business logic that only exists
within that page.

No, you're behind the times doing classic ASP programming. The UI of an
ASP.NET UI should be as dumb as possible nothing in the codebehind file
but methods in the codebehind file passing control to the presenter
method of a MVP that has the business rules for the method. And
presenter methods method acts upon the control based on business rules
in the presenter.

The presenter gives the control back to page. It's the presenter that
has the control and the Web page itself is dumb.

Given what Microsoft has already provided in the
UnitTesting framework I was asking if it was possible to leverage its members
to access UserControls within the ASPX much like we can access the members of
the page itself.

I don't think so, or it will be very hard to do so. It something I
wouldn't attempt it, using a test harness to test a Web page.
The intent was to write and evaluate a very simple test. This test only
touches one very specific function of the ASPX and in that sense I refer to
it as a "Unit Test". What this type of "Test" should actually be called is
academic in my opinion.

And here you are making the mistake of not knowing what type of test is
needed to pass the test and do it painlessly.

My question was simply given the tools available is
the below scenario intended to be possible and if so what are ways to
accomplish it. From other responses I am getting the impression that this is
currently not possible or extremely over complicated outside of MVC.

There is also Model View Presenter MVP a later offspring of MVC.

Fortunately, if somebody comes to this thread in the future wanting to know
the definition of "Unit Test" versus "Functional Test" they may also be
helped. Thanks for your contribution.

Not to be smart here, but you make the mistake of not knowing the
difference between the two and when to do a unit test and do it
successfully, based on expected behavior. As a opposed to doing a
functional test, that is based on expected functionality for expected
results unsuccessfully.

You can't mock away anything which is what unit test and behavior is about.
 
//The .ASPX in this case has logic responsible for identifying if a
particular
user has permission to perform a specific action. //


Since your other threads seem to indicate that "you're in deep now", then
there is not good solution for you.

My suggestion:
Move your logic out of the Presentation Layer. Move it into a BAL.
Write unit tests against the BAL.


Is it worth it? You'll have to answer that...........

But mistakes up front will always cost you 10X, 100X, 1000X down the road.


//better manage our testing needs based on our unique requirements.//
Your requirements are not unique. In fact, they are way too common.

Mistakes up front will always cost you 10X, 100X, 1000X down the road.

Try to learn from your mistakes and don't repeat them.

UnitTests (and for you managers out there, TIME TO DEVELOP UNIT TESTS)
should be a beginning of the project inclusion, not a retro fit.


I know its easy to say "you should have"...and you're looking for a solution
now, but this is one of those places that it is very hard to retro when its
a after-the-fact situation.




"Unit Test ASP.NET WebForm" <Unit Test ASP.NET
(e-mail address removed)> wrote in message
 
"Unit Test ASP.NET WebForm"
Thanks Andy,

Yes, the idea of leveraging automated tests to perform some of the routine
and mundane actions we pay people to do every month likely came too late.
In
my group, and I would suspect many groups in the IT world, we spend 300+
man-hours to test simple functionalities in our web application as part of
each release. Based on some of the simple things we do it seemed so
likely
that Unit Tests could perform some or most of these evaluations for us
thus
leaving different more complex evaluations to be performed by humans.

Well if that's a release every few months then the costs will be
considerable.
It ought to be relatively easy to justify spending time refactoring.

As others have suggested, start moving code.
Start adding tests.
Keep on chipping away and you should start to save some time.

I think it's probably worth mentioning that just because you have automated
unit testing in place you're never going to be able to stop doing manual
tests completely.
The next problem you will have is probably too strong a coupling to the
database.
You need to work on that as well and try and get to a position where you can
mock all dependencies and test just a class at a time.

Google mocking and inversion of control.
 
Ok, so I may be guilty in not properly focusing my question here. My
original question quickly turned into the equivalent of the Monday Morning
Quarterback cliche'. For those who recommended VS Team System, thank you. I
will be evaluating web tests via that tool. However, I'm still soliciting
some conversation regarding the actual question here: The UnitTesting
framework and usage of the PrivateObject class in ASPX files.

I'm looking for people familiar with the UnitTesting framework and the use
of the PrivateObject class to access aspx code behind classes. I realize
that unit testing is traditionally applied to the business layer which has
better places to be than in a aspx, but Microsoft enabled unit testing of
aspx files so I think this makes it a fair question.

If you are new to this thread please look at my original post and if you
have any experience using the PrivateObject class with a ASPX webform then
perhaps you can help me. Has anyone had any luck evaluating a user control
via a unit test on a aspx via the PrivateObject or some other approach?
 
Back
Top