I'm a C# and UI developer and I'm interested in writing unit tests in VS CodedUI for ASP.NET web applications. Most of the usages I've seen are integration tests, in that you write a test that points at the actual web page, run through some steps and test the output. I want something smaller and more granular, that is super simple for developers (read: lazy :P) to write.
My current setup looks like:
Web application, containing pages, controls, javascript, etc.
The web app also contains test pages - pages that contain a single user control in the markup, and some hard-coded data in the code-behind.
A CodedUI project that launches the test page, runs the test and asserts the output.
This is a nice start, but I'm looking to improve it.
The (first...) problem is that the test data and the test steps are in different locations - on the web app and codedUI project respectively. In regular developer unit tests, you write code that sets the data, then you do everything else, and everything you need is in one location. With my setup, a person looking at a test failure has to know to look at both the test and the page being tested.
A few ideas I had, and why they suck:
Put the test page in the codedUI project. This is a problem for a few reasons. User controls can't be easily tested, was my stopping point, but I believe there are plenty of others.
Pass in a query-string to the test page that provides the data. This isn't a terrible idea, but it might get unwieldy quickly.
Pass in a public class to be loaded by the test page which contains the test data. This requires the test page to have a reference to the testing project, which is no good.
Dynamically write and compile a test page in the codedUI test. I don't even want to start with this.
I suppose you are talking about unit testing your web pages with external data. With CUIT, you can do that with data driven CUIT.
Related
I am working on an Automated Test for my website I am building and some of the pages for the site implement the same elements and features. I am wanting to just have one testcase that has all the test that would be the same on multiple pages and then have the tests run multiple times using a different page model for each run. Is this even possible for I would prefer not to make multiple testcases with the exact same tests. I am using .Net6, Nunit, and Playwright.
this is what I am think of in my head but I know that the SuperClass cannot inherit multiple classes so I am needing it to be able to almost mimic a page model depending on what testcase of that test is being ran.
Picture of my Idea
Every time, when I deal with writing Tests in .NET (C#), I read, you can test DLLs only. But my app hasn't any DLLs and I want test some controllers and behaviours too. How it is possible, without creating an DLL project? Is it possible?
Hints are welcome.
Your unit test project(s) can still reference application projects like any other class library. It may be considered less ideal, but there's nothing preventing it from working. As the logic of your system grows, even a little bit, you'll certainly want to consider moving the business logic into Class Library projects and keeping the application layer as thin as possible.
I read, you can test DLLs only.
This was an oversimplification. What they probably meant was that you can test discrete functionality only. Regardless of what kind of project is hosting that functionality, the functionality itself has to be well defined, with separated concerns, and individually testable. If that's causing a problem in your design, then you have more work to do in order to unit test your code.
But to get started, simply create your unit test project and reference your other project. Then start writing tests for your individual units of functionality. Each test should be testing only one discrete thing, and should consist of the simple steps of:
Arrange
Act
Assert
Unit tests shouldn't require any additional setup, nor should they produce any side effects. This is where the "discrete" part comes in, each one should be individual and not depend on others.
I am modifying an application that does a lot of 'talking' to Microsoft Word. Right now, COM interop is used but I need to change it to Open XML. I would like to introduce unit tests for this but I am not sure how to do this.
This is one of the operations for example: A template word document contains some bookmarks. The application fills up the bookmarks with some dynamic data. Can I check if this executes correctly?
In order to unit test things like this, you need to design seams at the boundaries between your application and external code (Word, in this case).
For example, consider the following code:
var bookmarks = document.MainDocumentPart.Document.Body.Descendants<BookmarkStart>();
DoStuffWithBookmarks(bookmarks); // Imagine we want to unit test this method
Any code that invokes external code like this cannot be unit tested, as it is tightly coupled to the external code. That is, your tests would be testing your code and the external code, which introduces a lot of moving parts and a lot of opportunities for your test to break.
To deal with this, you introduce a layer of abstraction between your code and the external code. This lets you unit test your code by replacing the external code with test doubles.
Working with the example above:
var bookmarks = bookmarkProvider.GetBookmarks();
DoStuffWithBookmarks(bookmarks);
In your unit test, you would replace bookmarkProvider with a test double, giving you complete control over the conditions you're interested in testing.
Your production version of bookmarkProvider basically forwards its invocation to the external code:
IEnumerable<Bookmark> GetBookmarks()
{
var wordBookmarks = m_document.MainDocumentPart.Document.Body.Descendants<BookmarkStart>();
return ConvertToOurBookmarks(wordBookmarks); // wordBookmarks is external code!
}
Note: in this example the method does not return the Word objects directly - doing so would result in your code remaining tightly coupled to the external code. (So, not only is the process of retrieving bookmarks abstracted away, the bookmarks themselves are as well.)
This may seem like a lot of unnecessary work at first, but having the ability to test your code in complete isolation will pay dividends.
I have created one web application which includes login page and several other pages which include input controls.How i can perform Nunit testing on this pages.
It will be very helpful if you provide guideline for just only login page.
Login page is created using Login.aspx and Login.aspx.cs file.
It is not created using MVC.
You are confusing unit testing with automated UI testing. NUnit, as its name states is for creating automated tests for separated pieces of code. With this tests you check if concrete piece of code does what it should do. To check this you substitute all its dependencies (all classes/interfaces it interacts with) with stubs/mocks (more) which place the role of placeholders for real functionality. Thanks to this you can check if tested class behaves the way you expect it to behave because you have full control over its dependencies, so the only "unknown behavior" comes from object under test.
If you, however would like to automatize tests of user interface you can use special environments dedicated for this task. You can easily find dozens of frameworks for this, one of which is FitNess
I know Visual Studio offers some Unit Testing goodies. How do I use them, how do you use them? What should I know about unit testing (assume I know nothing).
This question is similar but it does not address what Visual Studio can do, please do not mark this as a duplicate because of that. Posted as Community Wiki because I'm not trying to be a rep whore.
Easily the most significant difference is that the MSTest support is built in to Visual Studio and provides unit testing, code coverage and mocking support directly. In order to do the same types of things in the external (third-party) unit test frameworks generally requires multiple frameworks (a unit testing framework and a mocking framework) and other tools to do code coverage analysis.
The easist way to use the MSTest unit testing tools is to open the file you want to create unit tests for, right click in the editor window and choose the "Create Unit Tests..." menu from the context menu. I prefer putting my unit tests in a separate project, but that's just personal perference. Doing this will create a sort of "template" test class, which will contain test methods to allow you to test each of the functions and properties of your class. At that point, you need to determine what it means for the test to pass or fail (in other words, determine what should happen given a certain set of inputs).
Generally, you end up writing tests that look similar to this:
string stringVal = "This";
Assert.IsTrue(stringVal.Length == 4);
This says that for the varaible named stringVal, the Length property should be equal to 4 after the assignment.
The resources listed in the other thread should provide a good starting point to understandng what unit testing is in general.
The unit testing structure in VS is similar to NUnit in it's usage. One interesting (and useful) feature of it does differ from NUnit significantly. VS unit testing can be used with code that was not written with unit testing in mind.
You can build a unit testing framework after an application is written because the test structure allows you to externally reference method calls and use ramp-up and tear-down code to prep the test invironment. For example: If you have a method within a class that uses resources that are external to the method, you can create them in the ramp-up class (which VS creates for you) and then test it in the unit test class (also created for you by VS). When the test finishes, the tear-down class (yet again...provided for you by VS) will release resources and clean up. This entire process exists outside of your application thus does not interfere with the code base.
The VS unit testing framework is actually a very well implemented and easy to use. Best of all, you can use it with an application that was not designed with unit testing in mind (something that is not easy with NUnit).
First thing I would do is download a copy of TestDriven.Net to use as a test runner. This will add a right-click menu that will let you run individual tests by right-clicking in the test method and selecting Run Test(s). This also works for all tests in a class (right-click in class, but outside a method), a namespace (right click on project or in namespace outside a class), or a entire solution (right-click on solution). It also adds the ability to run tests with coverage (built-in or nCover) or the debugger from the same right-click menu.
As far as setting up tests, generally I stick with the one test project per project and one test class per class under test. Sometimes I will create test classes for aspects that run across a lot of classes, but not usually. The typical way I create them is to first create the skeleton of the class -- no properties, no constructor, but with the first method that I want to test. This method simply throws an NotImplementedException.
Once the class skeleton is created, I use the right-click Create Unit Tests in the method under test. This brins up a dialog that lets you create a new test project or select an existing one. I create, and name appropriately, a new test project and have the wizard create the classes. Once this is done you may want to also create the private accessor functions for the class in the test project as well. Sometimes these need to be updated (recreated) if your class changes substantially.
Now you have a test project and your first test. Start by modifying the test to define a desired behavior of the method. Write enough code to (just barely) pass the test. continue on with writing tests/writing codes, specifying more behavior for the method until all of the behavior for the method is defined. Then move onto the next method or class as appropriate until you have enough code to complete the feature that you are working on.
You can add more and different types of tests as required. You can also set up your source code control to require that some or all tests pass before check in.