📜 ⬆️ ⬇️

Automated testing of a web application (MS Unit Testing Framework + Selenium WebDriver C #). Part 4: Finally writing tests

image
Introduction

Hi Hi! Well, it's time for the final part, in which I will give an example of simple tests written using wrappers from the previous parts of the article. As promised, I open public access to the working version of the framework (see links).

Links

Part 1: Introduction
Part 2.1: Selenium API wrapper - Browser
Part 2.2: Selenium API wrapper - WebElement
Part 3: WebPages - describing pages
Part 4: Finally writing tests
Framework Publishing

Go

And so, as an educational material, we will write a few tests Google translator. I am by no means going to do any test coverage, so I came up with 4 scenarios:

The main page is quite simple - we have an input field and a translation result. You don’t even need to click the Translate button to complete the transfer. The page description turned out like this:
namespace Autotests.WebPages.Root { public class Index : PageBase { #region Elements private static readonly WebElement SourceEdit = new WebElement().ById("source"); private static readonly WebElement ResutlText = new WebElement().ById("result_box"); private static readonly WebElement ClearButton = new WebElement().ById("clear"); private static readonly WebElement WebsiteTranslatorLink = new WebElement() .ByAttribute(TagAttributes.Href, Pages.Manager.Websites.Index.BaseUrl.ToString(), exactMatch: false); #endregion public void Open(string from, string to) { Contract.Requires(from != to); var url = new Uri(string.Format("{0}#{1}/{2}/", BaseUrl, from, to)); Navigate(url); } public string SourceText { get { return SourceEdit.Text; } } public string ResultText { get { return ResutlText.Text; } } public string Translate(string text) { SourceEdit.Text = text; if (!string.IsNullOrEmpty(text)) { Contract.Assert(WaitHelper.SpinWait(() => !string.IsNullOrEmpty(ResutlText.Text), TimeSpan.FromSeconds(10))); } return ResultText; } public void Clear() { Contract.Assert(ClearButton.Exists(10)); ClearButton.Click(useJQuery: false); } public void OpenWebsiteTranslator() { WebsiteTranslatorLink.Click(useJQuery: false); } } } 

I described 4 elements, three of them are on id, and the fourth - on the occurrence of the link in the href attribute. The class is inherited from PageBase, the code of which was cited in the previous article and is available in public. The overloaded Open method can open a translator with languages, for example en-ru. Well, the class also contains all the functionality that was needed as part of the automation of the scripts described earlier.
')
I will also give a description of the second page - website translator:
 namespace Autotests.WebPages.Root.Manager.Website { public class Index : PageBase { } } 

The class is empty, because in tests it is only necessary to check that the page has opened, we will not perform any actions on it.

Tests

First, let's write the base class:
 namespace Autotests.Suites { [TestClass] public abstract class SuiteBase { public TestContext TestContext { get; set; } [TestInitialize] public void TestInitialize() { Browser.Start(); } [TestCleanup] public void TestCleanup() { Browser.Quit(); } } } 

The class defines the preconditions and postconditions for each test, in this case the opening and closing of the browser. I note that the opening is not necessary, the browser will open when you first access it. In addition to TestInitialize and TestCleanup, there are also ClassInitialize and ClassCleanup, which also fulfill preconditions and postconditions, but for a group of tests from the same class when they are run together (sequentially). TestContext is also defined, which all tests can use, for example, to attach files to results.

And finally, the code of our tests:
 namespace Autotests.Suites { [TestClass] public class GoogleTranslateTests : SuiteBase { [TestMethod] public void TranslateText() { #region TestData const string languageFrom = "en"; const string languageTo = "ru"; const string textEn = "hello"; const string textRu = ""; #endregion Pages.Index.Open(languageFrom, languageTo); var result = Pages.Index.Translate(textEn); Assert.AreEqual(textRu, result, string.Format("{0} != {1}.", textRu, result)); } [TestMethod] public void CheckJavaScriptEscape() { #region TestData const string languageFrom = "en"; const string languageTo = "en"; const string javascript = "alert(1);"; #endregion Pages.Index.Open(languageFrom, languageTo); var result = Pages.Index.Translate(javascript); Assert.AreEqual(javascript, result, "JavaScript was executed."); } [TestMethod] public void ClearSourceText() { Pages.Index.Open(); Pages.Index.Translate(RandomHelper.RandomString); Pages.Index.Clear(); Assert.IsTrue(string.IsNullOrEmpty(Pages.Index.SourceText), "Source text was not cleared."); } [TestMethod] public void NavigateWebsiteTranslator() { Pages.Index.Open(); Pages.Index.OpenWebsiteTranslator(); Assert.IsTrue(Browser.Url.Contains(Pages.Manager.Websites.Index.BaseUrl), "WebsiteTranslator was not opened."); } } } 


I note that one test checks one logical action. Test data is in tests, but you can store them anywhere - in xml, in databases and any other repositories. I will also give a link to the DDT How to: Create a data-driven unit test

Conclusion

Thanks to everyone who read the article, asked questions and made suggestions! This concludes my story, and I myself am very glad that I managed to bring the matter to the end and talk about automated testing of a web application on Selenium C # in Runet, because there is very little information and examples in Russian so far. Good luck!

Source: https://habr.com/ru/post/181558/


All Articles