Code & QA

Test structure

Usage of previously created test reporting assumes definite and pretty strict structure of tests. For having well-designed and easy for understanding summary report all tests must be created under following rules:

· Every test collection class must be marked with attributes [TestFixture] or [TestClass]

· Every test collection class must be derived from BaseTest class where all additional functionality is located

· Every test method must be marked with [Test] or [TestMethod] attributes

· There are must be references to Logger and Mapping projects in the test project

clip_image001

· Structure of every test must be as following:

o Test scope – description of all test steps in a Dictionary<string, string> format. Key value is a description of a step and the value itself is a description of expected result. Usage of the test scope makes reading of a test pretty comfortable, it is very useful during the test review or in the future during changing or updating. It may save you a lot of time avoiding solving of puzzles about test objectives and reproducing test steps

var testScope = new Dictionary<string, string> {

{ “Open the application”, “start page is displayed” },

{ “Click iFrame in the left-side menu”, “iframe page content is displayed” },

{ “Verify expected text is displayed on the page”, “Text in the bottom part of content area is ” + expectedText }};

o Invocation of Report.StartTestCase method. The method creates new instance of TestCase class which will be saved then as a separate document with summary report on the current test run. It receives test scope instance as input parameter.

o Invocation of Report.RunStep() method. The method creates new instance of TestStep class which is added to the list of steps of current test case. All actions currently performed in the test are related to this current test step and therefore will be put under the step in the final report. To start the next step the method must be invoked once again. The number of the method invocations should be equal to the number of test scope notes. It assumes that every next Report.RunStep() matches to succeeding test scope line. It allows to count (and to display in summary report) a number of steps which have been run and which haven’t started with their correct statuses. If you won’t follow this rule nothing fatal will happen, you just can get incomplete or incorrect report, but it does not affect a test execution in any way.

o Report.AddInfo(), Report.AddWarning() and Report.AddError() methods may be invoked in a test. These methods add appropriate messages to current step and affects to its status (and also may affect to current test case status). The methods may be used as many times as necessary all over the test but only after RunStep() method has been invoked

· Every action in a test is performed in the following format:

TestedApplicationName.PageName.ElementName.ElementProperty;

or

TestedApplicationName.PageName.ElementName.ElementMethod([parameters]);

where

TestedApplicationName – a variable which represents class of an application under test, for example a web site. This variable is initialized in Setup() method of BaseTest class;

PageName is a property of application class which represents a single application page, for example a web page or an interactive element (such as form, table, frame, etc.) which is a part of the application;

ElementName is a property of PageName page which represents single web element located on the page. It may be simple element like a button, picture, textbox, panel, etc. or it may be complex element like table, tree view, diagram and so on;

Property or Method – property or method of ElementName web element. It may be simple property like Name or a method like Click() or TypeText(text);

· It is recommend that a single test should perform only one verification of a single functionality. This is a common practice. Though big and complex tests with a lot of navigation and conversion may reduce total execution time but they also mix up test objectives throwing them in the same heap and adding a mess to your code, test cases and test plans. So, please, follow the rule: one test – one verification.

· Testing actions described in a test must be performed only on a page(s) under test. No additional navigation or other actions must be described (or they must be put outside of the test). For example, you have to check that your tested site may perform a search and the result is correct. Assume you have first to log in, then to navigate from start page to a search page, then to perform a search and verify the result on the same page. Thus you need 1) to open the application, 2) to log in, 3) to navigate to search page, 4) only then you can perform the testing. With current framework you do not need and you do not have to do first three clauses. The test must start from a line like:

MyApplication.PageSearch.TextboxSearchForm.TypeText(searchQuery);

All previous action are performed automatically when you refer to Application.PageSearch property, this is what Application.Open<T> method is created for. Or you can use prerequisites conditions and explicitely invoke the method and set tested application in certain conditions:

TestedApplication.Open<HomePage>();

Such format allows you to see what element in which location is used currently and in which manner. Also every action in a test exactly repeats every action which real user must do manually to reproduce test steps. In addition such format will make an update or maintenance of a test much easier. Assume you have to log in an application. Compare:

Example #1:

Login(username, password); – a method for logging into a site

Assert.IsTrue(driver.FindElement(By.Id(“application_main_page_logo”)).Displayed);

Example #2:

Application.PageLogin.TextboxUsername.TypeText(username);

Application.PageLogin.TextboxPassword.TypeText(password);

Application.PageLogin.ButtonLogIn.Click();

Assert.IsTrue(Application.MainPage.IsLoaded);

In the first example Login() method does not show what it does. I can only guess that it does some work for logging into the site, but I can’t know exactly how it does this (correctly or not, suitable for the test objectives or not, and so on). Besides if I have to update the method due to application development changes (for example a ‘Domain’ field is added to the form), I can’t be sure that the updates will not affect other tests where the method is used. In case of usage of complicated methods with wide amount of branches the updates may cause a lot of problems and may easily add bugs to my methods.

In the second example I can easily add handling of ‘Domain’ field to the code not being afraid about the rest of tests.

Someone may say that in this case I must have to update a number of tests, but first please see what Application.Open<T> method is for and how it is invoked.

[row]
[column lg=”4″ md=”12″ sm=”12″ xs=”12″ ]
Test with the web elements [/column]
[column lg=”4″ md=”12″ sm=”12″ xs=”12″ ]
Table Of Content
[/column]
[column lg=”4″ md=”12″ sm=”12″ xs=”12″ ]
Assertion
[/column]
[/row]

Leave a Reply