I have set of tests and have to run it with two different SetUp in base class.
Here is screenshot
How can I improve it?
Create a single, parameterized test fixture. Pass in information about which setup (probably OneTimeSetUp) should be used to each instance of the fixture. The information will have to be constant values like strings so that it can be used as an argument to the attribute.
For example...
[TestFixture("setup1", 5)]
[TestFixture("setup2", 9)]
public class MyTestFixture
{
public MyTestFixture(string setup, int counter)
{
// You can save the arguments, or do something
// with them and save the result in instance members
}
[Test]
public void SomeTest()
{
// Do what you need to do, using the arguments
}
}
Related
I have created a TestFixture class with two test methods.
[TestFixture]
class SomeTests
{
[Test]
public void OpenScreen()
{
//Do something
}
[Test]
public void TestElement()
{
//Do something
}
}
My requirement is to run these tests based on inputs from an external file which looks like:
Test Value
Screen "Scr1"
Element "Ele1"
Element "Ele2"
Screen "Scr2"
Element "Ele3"
I am able to pass values to these test methods using:
[Test]
[TestCaseSource("GetTestValues")]
public void OpenScreen(string value)
{
//Do something
}
But I don't know how to run these tests in the exact order as received in the file. How can I achieve this?
Current order:
OpenScreen("Scr1")
OpenScreen("Scr2")
TestElement("Ele1")
TestElement("Ele2")
TestElement("Ele3")
Expected order:
OpenScreen("Scr1")
TestElement("Ele1")
TestElement("Ele2")
OpenScreen("Scr2")
TestElement("Ele3")
Edit: I'm using this for functional tests for testing some screens using Selenium.
The external file is a Json format string containing these values and GetTestValues simply deserializes the Json and returns the values.
Unfortunately, those test methods will be run by the NUnit runner and you won't be able to change the order in which they will run.
It seems what you are trying to do is to create some sort of acceptance test. What you can do is create a test method that wraps the sequence of steps and leave your OpenScreen and TestElement methods as simple helper methods:
[TestFixture]
class SomeTests
{
[Test]
public void TestInteraction() {
OpenScreen("Scr1")
TestElement("Ele1")
TestElement("Ele2")
OpenScreen("Scr2")
TestElement("Ele3")
}
private void OpenScreen(String arg)
{
//Do something
}
private void TestElement()
{
//Do something
}
}
There is the concept of "Page" objects, where you can write methods that represent actions you would perform on a screen or page. The OpenScreen and TestElement methods can be part of such object.
I heavily use the Autofixture AutoData Theories for creating my data and mocks. However this prevents me from using the InlineData Attributes from XUnit to pipe in a bunch of different data for my tests.
So I am basically looking for something like this:
[Theory, AutoMoqDataAttribute]
[InlineData(3,4)]
[InlineData(33,44)]
[InlineData(13,14)]
public void SomeUnitTest([Frozen]Mock<ISomeInterface> theInterface, MySut sut, int DataFrom, int OtherData)
{
// actual test omitted
}
Is something like this possible?
You'll have to create your own InlineAutoMoqDataAttribute, similar to this:
public class InlineAutoMoqDataAttribute : InlineAutoDataAttribute
{
public InlineAutoMoqDataAttribute(params object[] objects) : base(new AutoMoqDataAttribute(), objects) { }
}
and you'd use it like this:
[Theory]
[InlineAutoMoqData(3,4)]
[InlineAutoMoqData(33,44)]
[InlineAutoMoqData(13,14)]
public void SomeUnitTest(int DataFrom, int OtherData, [Frozen]Mock<ISomeInterface> theInterface, MySut sut)
{
// actual test omitted
}
Note that the inlined data, the ints in this case, must be the first parameters of the test method.
All the other parameters will be provided by AutoFixture.
With the latest AutoFixture, you can use Inline AutoData Theories
Uses the InlineData values for the the first method arguments, and then uses AutoData for the rest (when the InlineData values run out).
I am currently writing unit tests for a class that formats values based on parameters found in a big xml file.
The class I am testing receives another class in its constructor that provides functionality to parse and read the xml files. I think it is bad style to give the tested class a concrete instance of the xml reading class, because I believe doing so would result in testing the xml reading class every time I want to - in fact - test the formatting functions of the main class. All unit tests in the formatting class would fail if there was a problem in the xml reading class, which is clearly not the formatting class' fault.
So how should I proceed?
Obviously I would just create a mock of the xml reading class and pass that as an argument to the constructor. However the formatting class would use this instance to create about 5 private instances of other classes.
Because I don't know what these classes want to do (and honestly these tests should not care) I would like to mock away these private fields of the class I am testing.
Is that even ok to do? How would I do that using Moq?
-edit-
see the following example:
public class FormatterCore : IFormatterInterfaceIWantToTest
{
public FormatterCore(IConfigService service)
{
this.something = new SomeStuffA(service);
this.somethingThatINeed = new SomethingUserfull(service);
this.somethingElse = new SomeOtherStuff(service);
this.somethingTotallyDifferent = new SomeReallyUselessStuff(service);
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
In my example I want to test the method Format<T>() of the interface. To create an instance of the Formatter class, I'd need to pass an instance of a IConfigService implementation (which is expensive and cumbersome, because it would require different xml files and takes a while). My problem here is that I don't want to create an instance of the configService for every unit test because this would mean that I'd test the configService itself with every test in the FormatterCore unit.
In order to test FormatterCore you should not create an instance of a IConfigService implementation. You have to create and set up a mock object of IConfigService.
[TestClass]
public class FormatterCoreTest
{
Mock<IConfigService> сonfigServiceMock;
[TestInitialize]
public void Init()
{
сonfigServiceMock = new Mock<IConfigService>();
}
[TestMethod]
public void Format()
{
// arrange
var input = /* input value */;
var id = /* id value */;
var сonfigServiceMock
.Setup(services => services.YourMethodToMock())
.Returnes(/* expected result or behaviour */);
// act
var target = new FormatterCore(сonfigServiceMock.Object);
var result = target.Format</* AnyType */>(input, id);
// assert
/* Your asserts */
result.Should().Be(/* expectred result */);
Assert.AreEqual /* expectred result */, result);
}
}
Are types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff nested and can't be tested or public and it is possible?
If it is possible to test types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff then it is better to inject their instances into constructor of FormatterCore instead of creating them in the constructor.
public class FormatterCore : IFormatterInterfaceIWantToTest
{
ISomeStuffA something;
ISomethingUserfull somethingThatINeed;
ISomeOtherStuff somethingElse;
ISomeReallyUselessStuff somethingTotallyDifferent;
public FormatterCore(
ISomeStuffA someStuffA,
ISomethingUserfull somethingUserfull,
ISomeOtherStuff someOtherStuff,
ISomeReallyUselessStuff someReallyUselessStuff
)
{
this.something = someStuffA;
this.somethingThatINeed = somethingUserfull;
this.somethingElse = someOtherStuff;
this.somethingTotallyDifferent = someReallyUselessStuff;
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
Let your IoC be responsible for instance creation.
It will be needed to create and setup mocks for all dependencies in every test.
As you can't access the private variables of the XML formatting class (other than hacking into the class by reflection), and you can't be certain of when the other classes are created, I don't think you can mock them in the way you'd like to. Having to hack into a class to access private variables or methods for testing is a code smell - it means you have hidden testable functionality that should be exposed.
So, to expose that functionality, it seems like your best course of action would be to inject factories that the XML formatting class uses to create these other classes. Your XML reader/parser mock would be passed to the Create methods, and you would return appropriate mocks of those classes for the XML formatting class to use.
Alternatively, you could treat the XML formatting class as you would in an integration test - accept that other classes will be created with your XML reader/parser mock as a parameter, and set up that mock to expect calls from them as well.
I have a class with a static constructor which I use to read the app.config values. How do I unit test the class with different configuration values. I'm thinking of running each test in different app domain so I can have static constructor executed for each test - but I have two problems here:
1. I do not know how to run each test run in separate app domain and
2. how do I change configuration settings at run time?
Can someone please help me with this? Or anyone has a better solution? Thanks.
Personally I would just stick your static constructor into a static method then execute that method in the static block.
You don't need to test .Net being able to load data from config files.
Instead, try to concentrate on testing your own logic.
Change your class so that it gets the configuration values from its constructor (or via properties), and then test it as you would with any other dependency.
Along the way you have also moved your class towards SRP.
As per the configuration loading - concentrate this logic in a separate, non-static class.
EDIT:
Separate the configuration logic into another class. something like this:
public static class ConfigurationLoader
{
static ConfigurationLoader()
{
// Dependency1 = LoadFromConfiguration();
// Dependency2 = LoadFromConfiguration();
}
public static int Dependency1 { get; private set; }
public static string Dependency2 { get; private set; }
}
Then, when you instantiate your class, inject it with the dependencies:
public class MyClass
{
private readonly int m_Dependency1;
private readonly string m_Dependency2;
public MyClass(int dependency1, string dependency2)
{
m_Dependency1 = dependency1;
m_Dependency2 = dependency2;
}
public char MethodUnderTest()
{
if (m_Dependency1 > 42)
{
return m_Dependency2[0];
}
return ' ';
}
}
public class MyClassTests
{
[Fact]
public void MethodUnderTest_dependency1is43AndDependency2isTest_ReturnsT()
{
var underTest = new MyClass(43, "Test");
var result = underTest.MethodUnderTest();
Assert.Equal('T', result);
}
}
...
var myClass = new MyClass(ConfigurationLoader.Dependency1, ConfigurationLoader.Dependency2);
You could go on and use IOC containers, but your problem of testing MyClass with different inputs is solved by this simple testable design.
If you read from (Web)ConfigurationManager.AppSettings, that is just a NameValueCollection, so you can replace your code that reads ConfigurationManager.AppSettings directly with code, that reads from any NameValueCollection.
Just move out your actual configuration parsing to a static method from the static ctor. Static ctor calls that static method and passes ConfigurationManager.AppSettings, but you can call that parser method from the test code, and verify the config parsing without actually touching a file, or messing with appdomains.
But on the long run, really inject your configuration parameters as seldary suggested. Create a configuration class, read the actual values at application start, and set up your IoC container to supply the same configuration instance to all requesters.
This makes further testing easier too, because you classes don't read from a global static configuration instance. You can just pass in a specific configuration instance for differet tests. Of course create a factory method for your tests, to construct a global configuration, so you don't have to do it manually all the time...
I had the same exact problem recently. The only difference was that the configuration value was coming from database instead of app.config. I was able to resolve it using TypeInitializer.
[Test]
public void TestConfigurationInStaticConstructor()
{
// setup configuraton to test
// ...
// init static constructor
ReaderTypeInit();
// Assert configuration effect
// ...
// reset static ctor to prevent other existing tests (that may depend on original static ctor) fail
ReaderTypeInit();
}
// helper method
private void ReaderTypeInit()
{
typeof(< your class with static ctor>).TypeInitializer.Invoke(null, new object[0]);
}
I have unit test project called “MyClassTest” in TeamTest. This project has three TestMethods. Each method needs its own test initialization steps. But when I apply TestInitializeAttribute to three initialization methods, it says the attribute should not be used more than once. Then what should be the attribute to be used to initialize each test method in Visual Studio Team Test?
Reference:
VS Team Test: .Net Unit Testing with Excel as Data Source: Adapter Failed
How to create Startup and Cleanup script for Visual Studio Test Project?
VS 2010 Load Tests Results with custom counters
How to log unit test entry and leave in MSTest
Can a unit test project load the target application's app.config file?
According to MSDN the TestInitializeAttribute:
cannot be used more than once (AllowMultiple = false), and
cannot be inherited to create your own TestInitializeAttribute.
So, my suggestion is to create the Test Initialize Methods without the TestInitialize attribute. Then in the unique TestInitialize method check which is the current executed TestMethod and call the appropriate initialize method:
[TestClass]
public class UnitTest
{
public TestContext TestContext { get; set; }
[TestInitialize]
public void Initialize()
{
switch (TestContext.TestName)
{
case "TestMethod1":
this.IntializeTestMethod1();
break;
case "TestMethod2":
this.IntializeTestMethod2();
break;
default:
break;
}
}
[TestMethod]
public void TestMethod1()
{
}
[TestMethod]
public void TestMethod2()
{
}
public void IntializeTestMethod1()
{
//Initialize Test Method 1
}
public void IntializeTestMethod2()
{
//Initialize Test Method 2
}
}
If you have three test methods, and each method has its own initialization steps, then why are you moving initialization to method which will run before every test? Only benefit I see, is that nice switch block, which adds some lines to your source file. But it gives you drawback - looking on any of these test methods, you can't really tell in which context method will be executed. So, I use initialization method to setup only basic context, which is really used by all tests in fixture.
Just move context creation to arrange part of each method.
If you have several methods, which use common context, then just extract method, which will setup context for them, and call it at the arrange part. You also can split each context setup to several steps and reuse those steps (like it done in Given-When-Then tools like Specflow).
And, of course, creating different fixtures also option.
It's a bit of an old post, but I came up with the following which seems to work OK:
First, define an attribute class:
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class InitialiseWithAttribute : Attribute
{
public string Id { get; private set; }
public InitialiseWithAttribute(string id)
{
Id = id;
}
}
then define an extension method in some convenient utilities class:
public static bool IsInitialisedWith(this string testName, string value)
{
bool result = false;
Type testClassType = new StackFrame(1).GetMethod().DeclaringType;
MethodInfo methodInfo = testClassType.GetMethod(testName);
if (methodInfo != null)
{
InitialiseWithAttribute initialiseWithAttribute =
methodInfo.GetCustomAttribute<InitialiseWithAttribute>(true);
if (initialiseWithAttribute != null)
{
result = initialiseWithAttribute.Id == value;
}
}
return result;
}
Now write your tests, thus:
public TestContext TestContext {get; set;}
[TestInitialize]
public void TestInitialise()
{
if (TestContext.TestName.IsInitalisedWith("DoSomethingSpecial")
{
// ... Do something special
}
else
{
// ... Do something normal
}
}
[TestMethod]
[InitialiseWith("DoSomethingSpecial")]
public void MySpecialTest()
{
// The test
}
If they need three seperate inits; then they should probably be in three separate fixtures each with their own init!
At my job we pass in an argument to TestInitialize method to determine how we want initialization to work.
public partial class CommonActions
{
public void TestInitialize(bool adminTest)
{
try
{
if (adminTest)
{
//do stuff
}
We then have a standard initialization in class definition, which defaults to false.
[TestClass]
public class ProjectTestBase : FrameworkTestBase
{
public CommonActions common { get; set; } = new CommonActions();
[TestInitialize]
public void TestInitialize() => common.TestInitialize(false);
Then in the Test cases themselves you can override the TestInitialize for any test you want.
[TestClass]
public class SetReportsInAdmin : ProjectTestBase
{
[TestInitialize]
public new void TestInitialize() => common.TestInitialize(true);
We use a Boolean to tell if Admin test, which needs to have extra overhead for setup. Take this and apply whatever variables you want in a way the gives you multiple initialization through the use of one method.