Can we customize the output of XUnit and TestDriven.Net - c#

I am using XUnit with TestDriven.Net or Resharper test runner to execute my tests. I really like the BDD style of writing my tests so I was wondering if there is some what that we can modify the output of these frameworks?
I like to name my test with underscores and want to split the test name and format it in Given, When, Then format. Is it at all possible with these tools?

I'm not sure what you try to do. It seems that you want to change test names displayed on a certain test runnder. Displaying test names are actually depended on just test runner(tool). This means that we could customize names or couldn't by which test runner we use.
Checked out the following code, which could be the code that you want to do. If the code is not the case, at least, I think that it can show you some idea about how to customize test names.
public class Given_Foo
{
[Test]
public void Then_Bar_returns_correct_result()
{
Assert.True(flase, "Check out test names...");
}
}
public class TestAttribute : FactAttribute
{
public TestAttribute()
{
}
protected override IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo method)
{
yield return new CustomNamedTestCommand(method);
}
}
public class CustomNamedTestCommand : FactCommand
{
public CustomNamedTestCommand(IMethodInfo method) : base(method)
{
this.DisplayName = DisplayName.Replace("_", " ");
}
}

Related

How Do I Make C# Tests Run in Order?

I remember reading on a forum that C# Unit/Integration/Functional tests run in alphabetically order but that doesn't seem to be the case. I have 1 file that holds all of my tests and I put them from top to bottom in order like this.
A1_PostFirsttoRegisterClaimsAdmin
B2_CreateMasterWalletTest
C3_SendCoinsToProfile
D4_LoginTest
But when I click "Run All Tests," it runs in this order.
So how do I get the tests to run in order?
For xUnit you have to provide a TestOrderer.
public class AlphabeticalOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(
IEnumerable<TTestCase> testCases) where TTestCase : ITestCase =>
testCases.OrderBy(testCase => testCase.TestMethod.Method.Name);
}
Then you have to annotate your test class with an attribute to use this TestOrderer.
[TestOrderer("OrdererTypeName", "OrdererAssemblyName")]
public class MyTestClass
{
[Fact]
public void A1_PostFirsttoRegisterClaimsAdmin() { }
[Fact]
public void B2_CreateMasterWalletTest() { }
}
You can find more information about the ordering of unit tests in the Microsoft Docs

Is there a way to send a value from a unit test to another unit test?

I have a function which calculates some stuff and inputs it into a DB. This setup is important for all unit tests because they need some data to work on.
Sometimes i need to "flush" the DB, so all the unit tests point to the wrong ID.
Normally i just run the setup first and then change all the unit tests but this is taking to long tbh. Is there a way to automate this?
I would like to pass the generated ID into other unit tests.
So the idea was something like this:
[SetupFixture]
public class{
[Test]
public void SetupDB(){
setup();
//now marking the result somehow so other tests can pick the result up
return ID; //<--
}
}
public class OtherTests{
[Test]
[Get_ID_From_SetupDB]
public void testBaseOnID(int ID){
//we do stuff now with ID
}
}
PS: i have no problem switching the testing framework if you know a framework which can do this
Tests should be independent and you should generally never pass values between tests.
What you can do in your case, if all the tests are in the same class, is to have a variable in your class to hold the id and some global setup function that sets everything up and sets the variable to the correct id. In NUnit there is the [OneTimeSetUp] atribute for that.
[TestFixture]
public class MyTests
{
private int _testId;
[OneTimeSetUp]
public void SetItUp()
{
...
_testId = whatever;
}
[Test]
public void TestOne()
{
var whatever = _testId;
...
}
}

How to disable test parallel execution for all tests marked with custom Facts in XUnit.Net

We have an open source project for running remote XUnit.Net tests. The feature is that the body of the test is designed to run on a remote process and the results are serialized back to visual studio. The project can be found here.
https://github.com/Weingartner/XUnitRemote
For example a test might be like
[SampleProcessFact]
public void OutOfProcess()
{
_Output.WriteLine("Process name: " + Process.GetCurrentProcess().ProcessName);
Assert.Equal(1,1);
}
SampleProcessFact is a custom attribute declared so.
[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.SampleProcessFactDiscoverer", "XUnitRemote.Test")]
public class SampleProcessFactAttribute : FactAttribute { }
[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.ScheduledSampleProcessFactDiscoverer", "XUnitRemote.Test")]
public class ScheduledSampleProcessFactAttribute : FactAttribute { }
[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.SampleProcessTheoryDiscoverer", "XUnitRemote.Test")]
public class SampleProcessTheoryAttribute : TheoryAttribute { }
See https://github.com/Weingartner/XUnitRemote/blob/master/XUnitRemote.Test/XUnit.cs#L26 for source code.
However we would like an option so that if I tag my test case as SampleProcessFact then the test runner will only run the tests sequentially.
I am aware that I can tag all my test cases with TestCollection(string id) and it should prevent sequential running but this should be encapsulated in the SampleProcessFact tag if possible. This should work across all test cases in all assemblies.
My question only relates to the firing off of tests from visual studio. The remote part works fine but visual studio is calling our remote test case engine in parallel for all the tests.
Any ideas?
We made a checkin to our project that solved the problem.
https://github.com/Weingartner/XUnitRemote/commit/565e1dfb55f65ff0612afa40bc5d076c69bb739c
The general solution was to intercept the ITestMethod instance within XUnitRemoteTestCaseDiscoverer::Discover and rewrite the UniqueId of it's test collection.
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
if(CollectionId.HasValue)
testMethod = WrapTestMethod(testMethod, CollectionId.Value);
if (!Process.GetCurrentProcess().ProcessName.Equals(Path.GetFileNameWithoutExtension(_ExePath), StringComparison.OrdinalIgnoreCase))
{
yield return new XUnitRemoteTestCase(_DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, _Id, _ExePath);
}
else
{
foreach (var testCase in _DefaultTestCaseDiscoverer.Discover(discoveryOptions, testMethod, factAttribute))
{
yield return _TestCaseConverter(testCase);
}
}
}
and
private ITestMethod WrapTestMethod(ITestMethod testMethod, Guid uniqueId)
{
var testClass = testMethod.TestClass;
var testCollection = testClass.TestCollection;
testCollection = new TestCollection
(testCollection.TestAssembly, testCollection.CollectionDefinition, testCollection.DisplayName)
{
UniqueID = uniqueId
};
testClass = new TestClass(testCollection, testClass.Class);
testMethod = new TestMethod(testClass, testMethod.Method);
return testMethod;
}

How to distinguish between testsuite and testcase on the report

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.

Selective Ignore of NUnit tests

I want to ignore certain tests based on data I pulled from a configuration file during the TestFixtureSetUp. Is there a way to ignore running a test based on parameters?
[TestFixture]
public class MessagesTests
{
private bool isPaidAccount;
[TestFixtureSetUp]
public void Init () {
isPaidAccount = ConfigurationManager.AppSettings["IsPaidAccount"] == "True";
}
[Test]
//this test should run only if `isPaidAccount` is true
public void Message_Without_Template_Is_Sent()
{
//this tests an actual web api call.
}
}
If account we are testing with is a paid account, the test should run fine, if not, the method will throw an exception.
Would there be an extension of the attribute [Ignore(ReallyIgnore = isPaidAccount )]? Or should I write this inside the method and run 2 separate test cases for eg.
public void Message_Without_Template_Is_Sent()
{
if(isPaidAccount)
{
//test for return value here
}
else
{
//test for exception here
}
}
You can use Assert.Ignore() like Matthew states. You could also use Assert.Inconclusive() if you want to categorize the result differently.
This Question/Answer is slightly similar: Programmatically skip an nunit test

Categories

Resources