C# test, How to make delay between my tests? - c#

I have some tests that will call some external service. They have a limit on the API calls that I can call in every second so when I run all my tests, the last ones are going to fail because the limit on the API call is reached.
How can I limit number of concurrent tests/ put a delay afterwards/ make those special ones work on 1 thread?
My code is a normal test code using TestFixture like this:
[TestFixture]
public class WithExternalResource
{
SearchProfilesResponse _searchProfilesResponse;
[OneTimeSetUp]
public async Task WithNonExistingProfile()
{
_searchProfilesResponse= await WhenSearchIsCalled(GetNonExistingProfile());
}
[Test]
public void Then_A_List_Of_Profiles_Will_Be_Returned()
{
_searchProfilesResponse.Should().NotBeNull();
}
[Test]
public void Then_Returned_List_Will_Be_Empty()
{
_searchProfilesResponse.Should().BeEmpty();
}
}

You can limit your whole fixture to single thread with:
// All the tests in this assembly will use the STA by default
[assembly:Apartment(ApartmentState.STA)]
Or you can just mit certain tests to single thread with:
[TestFixture]
public class AnotherFixture
{
[Test, Apartment(ApartmentState.MTA)]
public void TestRequiringMTA()
{
// This test will run in the MTA.
}
[Test, Apartment(ApartmentState.STA)]
public void TestRequiringSTA()
{
// This test will run in the STA.
}
}
If you want to have a delay between all tests you could add a Thread.Sleep() in Setup or TearDown:
[SetUp] public void Init()
{
/* ... */
Thread.Sleep(50);
}
[TearDown] public void Cleanup()
{ /* ... */ }

Related

Is there any way to check if NUnit test is passed before the test is done

what I have here is my script in selenium c# using NUnit framework with multiple test as you can see below and it's connected to my TestRail and I am wondering if there is any way to check if my test is passed before the actual test is done.
[Test, Order(0)]
public void Login()
{
Navigate.ToLoginPage();
Log.In("user");
TestRailServer.Result("1"); //1 is testcase id
}
[Test, Order(1)]
public void RegisterUser()
{
Add.User();
TestRailServer.Result("2"); //2 is testcase id
}
The TestRailServer.Result("1") you see in the test is my connection in testrail it will decide if the test case in testrail is passed or failed based in the TestMethod(Login and RegisterUser)
Here's my code in TestRail connection
private static TestRailClient trClient;
public static void Result(string testCaseID)
{
ulong testRunID = "testRailID";
string testrailComment;
trClient = new TestRailClient("https://client.testrail.net/",
"username", "password");
var result = TestContext.CurrentContext.Result.Outcome.Status;
var testrailStatus = result switch
{
TestStatus.Failed => ResultStatus.Failed,
TestStatus.Passed => ResultStatus.Passed,
_ => ResultStatus.Retest
};
testrailComment = (testrailStatus == ResultStatus.Failed) ? TestContext.CurrentContext.Result.Message : "Passed";
trClient.AddResultForCase(testRunID, ulong.Parse(testCaseID), testrailStatus, testrailComment);
}
But the problem is the TestRailServer.Result is called before the test is done so I need a way to tell if my test passed before it executes the TestRailServer
Thank for the help if there is any and apology if you find it difficult to undestand
I've not used testrail, but I've used Nunit a fair amount.
My understand is that NUnit only knows if it has failed by doing an assert. If you don't have an assert in your code (and I don't see any at the level you've posted) your tests will always pass on completion. The challenge with your approach is that a failing assert will stop the test and you potentially won't get any result. That's how NUnit is designed - it's for unit tests that should take miliseconds afterall.
Instead of you ending every test line interacting with the reporter, move it to a [Teardown] method. That way the test completes (in a pass or fail state) and reporting is done after the event.
Something like:
public string testId;
[Test, Order(0)]
public void test1()
{
testId= "1";
Navigate.ToLoginPage();
Log.In("user");
//assert here
}
[Test, Order(1)]
public void test2()
{
testId= "2";
Add.User();
//assert here
}
[TearDown]
public void TearDown()
{
TestRailServer.Result(testId);
}
(and add asserts to the tests if you don't already) :-)

MSTest V2 Execute UnitTests sequentially -> [DoNotParallelize]

I have a question on running UnitTests sequentially. Unfortunately in scenario it is not an option to run them parallel or mock the database. The project is written in .NET core 3.1 and the UnitTests need to execute database operations before and after a Unittest has run.
After reading https://www.meziantou.net/mstest-v2-execute-tests-in-parallel.htm and a lot of other articles about sequential UnitTesting I came up with this (simplified):
BaseClass:
namespace XY.Test
{
[TestClass]
public class BaseTest: TimerModel
{
private static readonly DbCreator Creator = new DbCreator();
public static readonly DbConnectionManager ConnectionManager = new DbConnectionManager();
[TestInitialize]
public void BaseTestInitialize()
{
CreateTestData();
}
[TestCleanup]
public void BaseTestCleanup()
{
RemoveTestData();
}
public void CreateTestData()
{
RemoveTestData();
Creator.ExecuteSqlFromScript(ConnectionManager, #"Resources\CreateTestData.sql");
}
public void RemoveTestData()
{
Creator.ExecuteSqlFromScript(ConnectionManager, #"Resources\EmptyTestDataTables.sql");
}
}
}
TestClass:
[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.ClassLevel)] //<-- Also tried out Workers = 1 and Scope = ExecutionScope.MethodLevel
namespace XY.Test.Models
{
[TestClass]
public class TerminalConfigModelTest: BaseTest
{
[TestMethod]
[DoNotParallelize]
public void TestMethod1()
{
...
}
[TestMethod]
[DoNotParallelize]
public void TestMethod2()
{
...
}
}
}
For some reason, no matter what I do, the UnitTests are being executed parallel. What do I have to change in order to have them executed sequentially?
When I execute all tests in the test class, the TestInitialize of the base class is called twice before the TestCleanup is run. This causes the CreateTestData method to fail as indexes prevent a double insert of the test data.
What I would expect:
TestInitialize1 is called
TestMethod1 is executed
TestCleanup1 is called
TestInitialize2 is called
TestMethod2 is executed
TestCleanup2 is called
...
What happens:
TestInitialize1 is called
TestMethod1 is executed
TestInitialize2 is called before TestCleanup1 is called
TestMethod2 execution fails
Am I missunderstanding the [DoNotParallelize] option?
Paralelism isn't the problem here, my tests are definitely sequential and [ClassCleanup] also screwed me over. It's just unintuitive and weird, more info here.
I wanted to use ordered tests but it seems it's a legacy functionality only in MSTest-v1 and new versions of Visual Studio don't even support it.
Best thing i can tell you now is just don't use [ClassCleanup].
Use [TestCleanup] or [AssemblyCleanup].

How to run Multiple [TestMethod] in order?

i am asking how to run multiple test method in order that they are in same file.
For example i have this Unit Test File name
public class UniTest1
{
[TestMethod]
public void Login()
[TestMethod]
public void Logout()
[TestMethod]
public void SignIn()
[TestMethod]
public void ForgetPassword()
}
I want them in this order:
Login()
Logout()
ForgetPassword()
SignIn()
Just to clarify i want this order to check if this email already exist or not
If you structure your test cases to contain the code for the setup, action and assertions for that particular case, you do not need to run them in any particular order. A good advice would be to aim to not have any dependencies between the test cases, for instance, you should need to depend upon a "Login" test to have run prior to "LogOut". Instead the setup of the test code in the "LogOut" case would initiate the logged in session and set the stage for the "LogOut" action to happen.
If you find that multiple test cases share common setup code and teardown code, you could use the TestInitialize and TestCleanup properties on some methods, as such:
namespace UserInteractionTests
{
[TestClass]
public class UserAuthenticationTestt
{
[TestInitialize]
public void TestSetup()
{
/* Put your common initialization code here */
}
[TestMethod]
public void AnAuthorizedUserCanLogin()
{
/* put your setup, action and assertion here
from your system under test
*/
}
[TestMethod]
public void ALoggedInUserCanLogOut()
{
/* put your setup, action and assertion here
from your system under test
*/
}
[TestCleanup]
public void TestCleanup()
{
/* Put your common teardown code here.. */
}
}
}
You're setting up one big Test with multiple steps but not four dedicated tests.
Here an example:
public class UniTest1
{
[TestMethod]
public void LoginSuccess()
{
// Try to Log in
o.Login("user", "pw");
Assert.AreEqual(true, o.ImLoggedIn);
}
[TestMethod]
public void LoginWrongPw()
{
// Try to Log in
o.Login("user", "wrongpw");
Assert.AreEqual(false, o.ImLoggedIn);
}
[TestMethod]
public void LogOutSuccess()
{
// Login
o.Login("user", "pw");
// Check if steup is completed
Assert.AreEqual(true, o.ImLoggedIn);
bool ok = o.LogOut();
Assert.AreEqual(true, ok);
}
[TestMethod, ExpectedException(NotLoggedInException)]
public void LogOutNoLogout()
{
// Try to Log in
Assert.AreEqual(false, o.ImLoggedIn);
bool ok = o.LogOut();
}
}
As you can see every test is independend from the others.
If you need a logout-test you have to setup the environment for it and not "hope" that other tests to so.

How to Run parallel Test Method in single class using Nunit, C# -ThreadSafe Driver

I am new to C#, i am not able to make driver thread safe. I am able to open the two browser as soon as second browser opens, first driver lose its references.
below is my code i have three class
namespace TestAutomation{
[TestFixture]
[Parallelizable(ParallelScope.Children)]
public class UnitTest1 : Setup
{
[Test, Property("TestCaseID","123")]
public void TestMethod1(this IWebDriver driver1)
{
driver1.Navigate().GoToUrl("https://www.google.com");
driver1.FindElement(By.Name("q")).SendKeys("test1");
Thread.Sleep(10000);
}
[Test, Property("TestCaseID", "234")]
public void TestMethod2()
{
driver.Navigate().GoToUrl("https://www.google.com");
driver.FindElement(By.Name("q")).SendKeys("test2");
Thread.Sleep(15000);
}
}}
Setup Class
namespace TestAutomation{
public class Setup:WebDriverManager
{
[SetUp]
public void setupBrowser()
{
driver = new ChromeDriver("C:\\Users\\Downloads\\chromedriver_win32");
}
[TearDown]
public void CloseBrowser()
{
driver.Close();
driver.Quit();
// driver.Close();
//driver.Quit;
}
}}
Webdrivermanager
namespace TestAutomation{
public class WebDriverManager
{
public IWebDriver driver { get; set; }
}
}
i am looking for a solution like ThreadLocal injava where i can get and set the driver for each thread in the setup method
Remove the SetUp & TearDown Attributes for the methods and call them explicitly. When you use these method attributes, it starts sharing resources across tests in the same class or inherited classes.
The below solution works perfectly fine. I have developed a project in which you can execute browser tests in parallel (method level parallelization). You can modify the project as per your needs.
Project Link: www.github.com/atmakur
[TestFixture]
class Tests
{
[Test]
public void Test1
{
using(var testInst = new TestCase())
{
testInst
.Init()
.NavigateToHomePage();
}
}
}
public class TestBase:IDisposable
{
private IWebDriver BaseWebDriver;
private TestContext _testContext;
public NavigatePage Init()
{
_testContext = TestContext.CurrentTestContext;
BaseWebDriver = new ChromeDriver();
.
.
.
}
public override void Dispose()
{
//Kill Driver here
//TestContext instance will have the AssertCounts
//But The Testcontext instance will have the result as Inconclusive.
}
}
You are doing two contradictory things:
Using a new browser for each test.
Sharing the browser property between the tests.
You should do one or the other. If you want to create a new browser for each test, don't store a reference to it where the other test also accesses it.
Alternatively, use OneTimeSetUp and OneTimeTearDown and only create the browser once. However, in that case, you can't run the tests in parallel.

How to get Setup and Teardown working per-Fixture?

I have the following:
[TestFixture]
public class SmokeTest : BaseTest
{
[Test(Description = "Should Do This")]
public void ShouldDoThis()
{
//Tests,Assertions,etc
}
[Test(Description = "Should Do That")]
public void ShouldDoThat()
{
//Tests,Assertions,etc
}
}
With BaseTest defined as:
[TestFixture]
public class BaseTest
{
[TestFixtureSetUp]
public void SetUp()
{
// set up browsers
}
[TearDown]
public void Dispose()
{
// dispose browsers
}
}
The goal is to have the selenium browsers' drivers created once per testFixture (// set up browsers), then at the end of the Fixture, torn down. Right now the browsers are being killed after the first test though, and the second test fails with some "Unable to connect to the remote server" error.
I'd like to target the first problem here - why is the TearDown method being called after the first test?
You need to use the TestFixtureTearDown attribute instead of the TearDown attribute in your base test. The TestFixtureTearDown attribute will cause the method to be run only once at the end of all of the tests in the fixture.

Categories