I am building a test framework using NUnit + SpecFlow + Selenium. I have a solution with two projects(so far). at the top level I have the Suite Framework so: PageFactory, DriverFactory, CommonPages, etc. The other project has the actual tests(cucumber), test steps and test pages.
Both projects have the same NuGet packages installed and the second has references to the Suite Framework.
Everything seems to be fine: I have [BeforeTestRun], [BeforeScenario] and [AfterTestRun] on the framework and when I run the test it is able to find them and execute them but when the code gets to the Cucumber features it just skips them, I mean it highlights them but it does not drill into them.
I checked the steps definitions and they are there (I can go to definition and it does find them no matter in which project they are) and the binding seems to be right.
Going to definition
Finding the definition
So far this is an example of my code:
feature:In this file the background refers to file placed on the framework project and the scenario to the feature steps inside the same project.
Feature: Reports
As an admin
I want to access to the Reports
So I can see the information related to my product
Background:
When I navigate to the 'Reports' page
And I navigate to my product reports
#Regression
Scenario: I can open the report
When I click on the 'overall' tile
Then the report is displayed
And the data matches the database
Backgorund steps:
using UI.Suite.CommonPages.Pages;
using OpenQA.Selenium;
using TechTalk.SpecFlow;
namespace UI.Suite.CommonPages.Steps
{
[Binding]
public class SideBarNavigation
{
private readonly SideMenuComponent sideMenuComponent;
public SideBarNavigation(IWebDriver driver)
{
sideMenuComponent = new SideMenuComponent(driver);
}
[When(#"I navigate to the '(.*)' page")]
public void NavigateTo(string page)
{
sideMenuComponent.SideMenuNavigation(page);
}
}
}
Scenarios steps:
using NUnit.Framework;
using TechTalk.SpecFlow;
using UI.Products.Tests.Pages;
using OpenQA.Selenium;
namespace UI.Products.Tests.Steps
{
[Binding]
public class ReportsSteps
{
private readonly ReportsPage _reports;
public ReportsSteps(IWebDriver driver)
{
_reports = new ReportsPage(driver);
}
[When(#"I navigate to my product reports")]
public void WhenINavigateToMyProducts()
{
_reports.SelectMyProduct();
}
[When(#"I click on the '(.*)' tile")]
public void WhenIClickOnAGivenReport(string report)
{
_reports.SelectReportTileAndConfig(report);
}
[Then(#"the report is displayed")]
public void TheReportDisplays()
{
Assert.IsTrue(_reports.HasReportLoaded(), "The report has not loaded correctly");
}
[Then(#"the data matches the database")]
public void TheDataDisplays()
{
Assert.IsTrue(_reports.DoesUIMatchDB(), "The data on the database does not match the UI");
}
}
}
Thanks for your help.
Related
I noticed for my little project that when importing classes some use full folder reference while otheres don't.
Here is code from project Mini that i am working on.
Models folder
Contains two entities, Auto and Airplane
namespace Mini.Models {
public class Auto {
// code and stuff
}
}
namespace Mini.Models {
public class Airplane {
// code and stuff
}
}
Services folder Contains single service class
namespace Mini.Services
{
public class AutoService : IAutoService {
public bool Get() {
var autoObject = new Models.Auto(); // notice how it references Models folder
var planeObject = new Airplane(); // Same folder but not referencing Models in front of it
// other code
}
}
public interface IAutoService {
bool Get();
// others
}
}
While not a major bugbear, it is still annoying that two classes in same folder get referenced differently, and i cannot figure out why.
Any advice would be appreciated.
Error Message when removing Models folder
Error CS0118: 'Auto' is a namespace but is used like a type (34, 27)
Based on the error message you have provided:
Error CS0118: 'Auto' is a namespace but is used like a type (34, 27)
It would appear that you have a namespace called Auto. Imagine the following example:
namespace MyApp.Auto
{
class Test
{
}
}
namespace MyApp
{
class Auto
{
}
class MyTest
{
private Auto test;
}
}
Because you can see, from the MyApp namespace, both a class called Auto and a namespace called Auto (either namespace MyApp.Auto or simply namespace Auto), C# isn't sure which one you want. As such, it's forcing you to be specific in choosing one or the other.
The easiest solution is to change the MyApp.Auto namespace to something else.
This is not fix but explaining with proper code sample (and why ).
namespace Mini.Models
{
public class Auto
{
// code and stuff
}
}
namespace Mini.Models
{
public class Airplane
{
// code and stuff
}
}
namespace Mini.Auto
{
public class OtherAirplane
{
// code and stuff
}
}
namespace Mini
{
using Mini.Models;
using namespaceAuto = Auto ; /// this also not fix the issue.
class NamespaceIssue
{
void execute()
{
var autoObject = new Auto(); // Error
var planeObject = new Airplane(); // Same folder but not referencing Models in front of it
// other code
}
}
}
now you can see some were in code you have "Mini.Auto" namespace , and it is couching issue.
i tested for VS 2015 have same issue. maybe we have to report to VS team or it is by design .
The issue seemed to be with VS2017 or the way it created the project first time around.
Upon starting brand new project (ASP Core 2.2, Web API, with https enabled and docker disabled), and using same classes the issue was non-existant.
Using Selenium C# web driver with NUnit for automation. I am generating Allure report using command line and my report gets fantastically created but I need help on the following issue:
I have the following structure using Page object model (2 Test and 1 Page). Now when I see the report it shows at the top Test run (2 testsuites, 2 testcases) and each testcase is a testsuite. I want it to say 1 testsuites, 2 testcases. How do I do that?
namespace ApplicationName.TestCases
{
[TestFixture]
class VerifyCreateOrder
{
IWebDriver driver;
[SetUp]
public void Initialize()
{
driver = new FirefoxDriver();
}
[TestCase]
public void doCreateOrder()
{
LoginPage loginPage = new LoginPage();
//some Assertion
}
}
}
namespace ApplicationName.TestCases
{
[TestFixture]
class SearchOrder
{
IWebDriver driver;
[SetUp]
public void Initialize()
{
driver = new FirefoxDriver();
}
[TestCase]
public void doSearchOrder()
{
LoginPage loginPage = new LoginPage();
//some Assertion
}
}
}
The below is my LoginPage Page object:
namespace ApplicationName.Pages
{
class LoginPage
{
public void doLogin(IWebDriver driver, String username, String password)
{
driver.Navigate().GoToUrl("http://www.myxyzsite.com");
driver.FindElement(By.Id("xyz")).SendKeys(username);
driver.FindElement(By.Id("xyz")).SendKeys(password);
driver.FindElement(By.Id("xyz")).Click();
}
}
}
I read about the NUnit suite attribute at http://www.nunit.org/index.php?p=suite&r=2.5.5 and created a c# class with enumerator as described but how do i call it/wire it? What changes do I need to make for my test classes?
namespace NUnit.Tests
{
public class MyTestSuite
{
[Suite]
public static IEnumerable Suite
{
get
{
ArrayList suite = new ArrayList();
suite.Add(new VerifyCreateOrder());
suite.Add(new SearchOrder());
return suite;
}
}
}
}
I want it to say 1 testsuites, 2 testcases. How do I do that?
Without adding a Suite or similar, you could put both Test cases into the same TestFixture, since that's what the testsuite output is built from. You may be able to do that using a partial class, or you can simply conflate the two classes. However, your Suite solution is a better choice.
What changes do I need to make for my test classes?
Call NUnit with the option /fixture:NUnit.Tests.MyTestSuite.
Note that all of this has changed with NUnit 3 and the Suite attribute is gone. I can't see any way to do what you want in NUnit 3 short of reorganizing your test cases.
If it's very important to merge tests into suites, you can use XSLT. The NUnit test result schema is quite straightforward and easy to manipulate using XSLT.
I am new to automation testing and selenium and have been watching alot of selenium tutorials. I realized that selenium test cases are written in 2 formats and im not sure which one to go with.
1)
namespace SeleniumTests
{
[TestFixture]
public class Login
{
private IWebDriver driver;
private StringBuilder verificationErrors;
private string baseURL;
private bool acceptNextAlert = true;
[SetUp]
public void SetupTest()
{
driver = new FirefoxDriver();
baseURL = "http://chapters.com";
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
driver.Quit();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public void TheLoginTest()
{
driver.Navigate().GoToUrl(baseURL");
driver.FindElement(By.Id("loginCtrl_UserName")).Clear();
driver.FindElement(By.Id("loginCtrl_UserName")).SendKeys("operations");
driver.FindElement(By.Id("loginCtrl_Password")).Clear();
driver.FindElement(By.Id("loginCtrl_Password")).SendKeys("welcome");
driver.FindElement(By.Id("loginCtrl_LoginButton")).Click();
driver.FindElement(By.Id("btnInitialLoad")).Click();
Assert.AreEqual("Chapters", driver.Title);
}
}
}
2)
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace TestProject1
{
public class UnitTest1
{
public void main()
{
FirefoxDriver driver = new FirefoxDriver();
string baseURL = "http://seleniumhq.org/";
driver.Navigate().GoToUrl(baseURL);
driver.FindElement(By.LinkText("Projects")).Click();
driver.FindElement(By.LinkText("Selenium IDE")).Click();
Assert.AreEqual(driver.FindElement(By.XPath("//div[#id='mainContent']/table/tbody/tr/td/p/b")).Text, "Selenium IDE");
driver.Close();
}
}
}
Which one do I go with?
Thanks
The second scenario is simple sequential flow of statements without added advantage of any frameworks like Junit,TestNG,Nunit. It is good for people who have just started with Selenium 2.0 and want to practice with different methods provided by webdriver.
The first scenario is logical division of the code into different annotations provided by Nunit, with these annotations one can get tremendous power of the underlining framework being used, in your case Nunit, these annotation are automatically called by the Nunit framework in a defined order. Apart from this there are multliple other functionalities provided by these frameworks like Reporting,Assertions,Support for Mock Objects,etc
Always use the first scenario for writing Selenium code because along with understanding of the webdriver code, one also gets hang of the underlining framework.
I am trying to do some BDD testing using Specflow, NUnit and WatiN. I am using TestDriven.NEt to run the test. Here is my first test:
[Binding]
[TestFixture, RequiresSTA]
public class RegisterUserSteps
{
private IE _ie = new IE();
[When(#"the user visits the registration page")]
public void WhenTheUserVisitsTheRegistrationPage()
{
_ie.GoTo("http://localhost:1064/Register/");
}
[When(#"enter the following information")]
public void WhenEnterTheFollowingInformation(Table table)
{
foreach(var tableRow in table.Rows)
{
var field = _ie.TextField(Find.ByName(tableRow["Field"]));
if(!field.Exists)
{
Assert.Fail("Field does not exists!");
}
field.TypeText(tableRow["Value"]);
}
}
[When(#"click the ""Register"" button")]
public void WhenClickTheRegisterButton()
{
ScenarioContext.Current.Pending();
}
[Then(#"the user should be registered")]
public void ThenTheUserShouldBeRegistered()
{
ScenarioContext.Current.Pending();
}
}
The problem is that it never goes to the
[When(#"enter the following information")]
public void WhenEnterTheFollowingInformation(Table table)
It just launches the browser and perform the first step. Am I missing something?
Without looking at the test, it seems you are missing an important step (Given). Usually it is like this:
Given I go to some page
And all the set up data are available - optional
When I enter the following info
And I click "Register" button
Then I see something
Basically the steps are GWT (Given, When, Then). It's Gherkin language, so if you google for it you'll see more info. When you have multiple things for a given step, you have to use And, example, When ...... And......., not When...... When........
I'm trying to test a file (Account.cs) using testfile (AccountTest.cs). I run OSX 10.6 with Mono Framework (and nunit-console).
Below is Account.cs
namespace bank
{
using System;
public class InsufficientFundsException : ApplicationException
{
}
public class Account
{
private float balance;
public void Deposit(float amount)
{
balance+=amount;
}
public void Withdraw(float amount)
{
balance-=amount;
}
public void TransferFunds(Account destination, float amount)
{
destination.Deposit(amount);
Withdraw(amount);
}
public float Balance
{
get { return balance;}
}
private float minimumBalance = 10.00F;
public float MinimumBalance
{
get{ return minimumBalance;}
}
}
}
And here is AccountTest.cs:
namespace bank
{
using NUnit.Framework;
[TestFixture]
public class AccountTest
{
[Test]
public void TransferFunds()
{
Account source = new Account();
source.Deposit(200.00F);
Account destination = new Account();
destination.Deposit(150.00F);
source.TransferFunds(destination, 100.00F);
Assert.AreEqual(250.00F, destination.Balance);
Assert.AreEqual(100.00F, source.Balance);
}
[Test]
[ExpectedException(typeof(InsufficientFundsException))]
public void TransferWithInsufficientFunds()
{
Account source = new Account();
source.Deposit(200.00F);
Account destination = new Account();
destination.Deposit(150.00F);
source.TransferFunds(destination, 300.00F);
}
}
}
I compile these two files by:
mcs -t:library Account.cs
mcs -t:library -r:nunit.framework,Account.dll AccountTest.cs
And get Account.dll and AccountTest.dll respectively.
To run the test I use:
nunit-console AccountTest.dll
and it runs as it should, giving me the appropriate failures and passes.
However, now I want to use mono's code coverage ability to asses these tests. I'm reading the tutorial http://mono-project.com/Code_Coverage to run the coverage tools. And to use it I would need to compile into *.exe file rather than *.dll file.
If someone could help me with the main class of the AccountTest.cs file, I would be able to then compile it in exe and from there use the coverage tool.
Thanks a tonne in advance.
You are pointing to the right page:
"To use similar options while running unit tests directly with nunit-console2, specify MONO_OPTIONS as follows: MONO_OPTIONS="--profile=monocov:+[MyAssembly]" nunit-console2 MyTestAssembly.dll"
You can run your unit tests and get code coverage by setting the option.
You might like to try out Baboon my new mono code coverage tool. The monocov and cov profilers only check for method entry/exit while Baboon is able to check the coverage of each line of each method in your program, including static initializers and private members.
$ echo assembly:MyTestFixture > ~/test.cfg
The above creates a config file that tells baboon to look at code in your assembly. Then set and environment variable and run it:-
$ BABOON_CFG=$HOME/test.cfg covem.exe /opt/nunit/nunit-console.exe MyTestFixture.dll
Give it a spin! Works best on mono 3.x, You'll need gtk-sharp installed to run the GUI or you can generate a basic html report.
I've been writing it on Linux but it should run equally well on OSX.
Feature requests/bug reports most welcome!