A Short Background
Almost 4 months ago I switched companies and dove head first into a pool full of new technologies. After working 7 years with Java and Java technologies, all of the sudden, I used everything… except for Java.
After spending the first-month doing shadow work on a hybrid mobile project, I joined the project I am currently working on. The project was for an Intellectual Property (IP) protection company. Everything revolves around Microsoft technologies so, naturally, the automation framework that was already in place was developed in Visual Studio 2017 using C# technologies. The switch from Java to C# (as programming languages) is not as difficult as Java to Python, Ruby, JavaScript. Or so I thought…
The Problem
It is always challenging when joining a project that has the skeleton for an automation solution in place and the team you are joining appears to already be having some success with that solution. After all, it is the QA dream to be part of the ‘birth’ of the automation solution: when all the important decisions are made, all the technologies are picked, when the architecture is decided, and so on.
Energized by the change, I set up the project and got to work. I started running the first C# tests of my QA career. I spent time understanding the automation solution, read tons of documentation on Visual Studio, C#, .Net, and related technologies.
After I got more familiarized with the structure and the conventions, I started putting together my first tests. As one can imagine, a lot of copy and pasting from one place to another was involved at first.
Going over the tests and working on the ones I was assigned to do, I noticed something weird. The test method implementations were not doing anything to verify the steps they were performing. They were not asserting for anything: not for an element present, not for a text present, not for a visible button, not for an expected image, NOTHING. Instead of that, every method was part of a try-catch block.
public void AddStudent() { try { addButton.Click(); Browser.Wait(3); firstName.SendKeys("FirstName"); Browser.Wait(3); secondName.SendKeys("SecondName"); age.SendKeys("19"); majoringIn.SendKeys("Computer Science"); Browser.Wait(1); } catch(Exception E) { Console.WriteLine("Cannot add student " + E.Message); throw E; } }
The same thing was happening when actually calling for the test methods in the framework:
public void CreateGradeCard() { try { LoginPage.Goto(); LoginPage.UserLogin(UserName: "user", Password: "password"); Student.AddStudent(); Student.EditStudent("StudenName"); Student.SaveTemplate(); Student.RemoveStudent("StudentName"); Header.SignOff(); } catch(Exception E) { Console.WriteLine("Test Fail " + E.Message); } }
At first, I tried following the same pattern because I was a C# newbie. I put together the first batch of tests and ran them. I followed the browser and noticed that not all steps from the test method got executed, but when I switched back to Visual Studio, the test run was marked in Green
. Opening the Output
looked like below:
So, the test passed, but we know for sure one step was not performed because of the Could not find element
error. Basically, there were times when big chunks of steps were not even executed, but the test outcome would still be Passed
. This would make the automation solution unreliable.
The Solution
A “good practice” in automation testing and especially UI functional testing, which is the case here, is making sure that what we EXPECT to happen, DID happen.
Enter: TESTING ASSERTIONS.
A test assertion is defined as an expression which encapsulates some testable logic specified about a target under test. As an example:
- Imagine we have to test a login page for the happy flow, so the successful login. How do we know that the login was successful if we just perform steps and not assert anything? To have a reliable test we need to test that after login, we land, for example, on the expected page. So assert on the page title.
I’ve been doing this my whole QA life and I expected it to be straightforward in C# as well.
After removing the try-catch blocks from the tests I was designing, I started to type Assert.
and expected Visual Studio to suggest the library that needed to be imported (you know, Java-style), but nothing happened.
So I started Google-ing. After a couple of hours (yeah, don’t laugh, I was a newbie in C#) this stackoverflow post from 2012 appeared on the search result page with the solution.
Basically, the C# framework works with references:
Note the Microsoft.VisualStudio.QualityTools.UnitTestFramework reference above. It is the reference that allows users to work with Assert class. It is also one of the references that are not added to a test project by default in Visual Studio.
Comparing with my previous experience, when setting up a project in Java, there were no other references/classes/modules to add individually. You would just type something like: Assert.
and you would get all the suggestions that you need. But for this particular framework, in order to have it available in the automation solution, you need to add it explicitly, like below:
- Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll.dll can be found in “C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\” and can be added to the project by right-clicking
References
andAdd Reference
:
Once added, it should be visible in the Reference Manager
window:
Note: the path where the .dll can be found may vary, depending on the VS installation path.
Once the setup is in place, all that is left to do is importing the actual library in the class you want (this also needs to be done, as there are no suggestions to auto-import it):
using Microsoft.VisualStudio.TestTools.UnitTesting;
Type Assert.
in the class now.
The entire assert package is available. Now, if the tests will fail, the error will look like this:
Now we can start creating more reliable automation solutions for our UI functionality testing.
Conclusion
The problem may seem trivial to an expert C# user, but it took a little time for the untrained eye to find the solution. This is meant to help whoever finds themselves working with a C# automation solution and needs to use assertions to build a more reliable test framework.
It also targets the users that make the switch to C# related technologies and may find this problem in the setup process or later on.
Ciprian Simon
Related Posts
-
How to Use Test Data for Increased Software Quality
Test data is a major influencer of test reliability and should be the main concern…
-
Pytest-bdd, TestRail, and Test Artifacts
This is part of the Python Automation Testing blog series. You can review the code…