Is it possible to use xUnit with LINQPad?
It would be great to be able to write some tests for concepts being designed in LINQPad first. It's easier than adding yet another ConsoleApp23423894238 just to be able to quickly write some unit tests.
Yes, it is possible to use xUnit with LinqPad. I have updated this answer to give you the latest information, but the original answer I gave also gives you some insights and links regarding the usage of xUnit, so I kept it for your reference.
UPDATE: Latest version of LinqPad 6 or 7 (since V 6.9.x and higher, see 6.9 Release Notes section) has now built-in XUnit support via the new menu item Query / Add XUnit Test Support. This will add a query with required boilerplate code referenced via #load so you can start testing facts and theories instantly. You can run the example test method by pressing Alt+Shift+T.
For example, add the following new theory to the boilerplate code (right after the main method, put it inside the private::Tests region):
#region private::Tests
[Theory]
[InlineData(1)]
[InlineData(3, 6)]
[InlineData(5, 7, 9)]
void OddNumbers(params int[] values)
{
static bool IsOdd(int value) => value % 2 == 1;
foreach (var value in values)
{
Assert.True(IsOdd(value), $"IsOdd({value}) is false");
}
}
#endregion
Press Alt+Shift+T to run all tests and check the result.
Note: It also adds a file XUnit.linq to your query directory the first time you add XUnit Test support - this is a mini library to support xUnit tests and you should not touch it unless you know exactly what you're doing. For example, you can modify this file to change the way the test summary is being displayed (for example, you can add the parameter Func<UserQuery.TestResultSummary, bool> filter = null to the method RunTests and add .Where(filter) inside the query if filter is not null. This allows you to filter the results of the test summary).
For example: RunTests(filter: f => f.MethodName.StartsWith("Unit")); will only display the tests in the summary which names start with "Unit".
Dynamically skippable unit tests
You can modify the xunit script LinqPad 6 provides to support skippable unit tests (NUGET package XUnit.SkippableFact, detailed description see the link "dynamically skipping test and theory" at the end of this answer).
Make the following changes in xunit:
function RunTests - add:
runner.OnTestSkipped = info => AddTestResult(info);
class TestResultSummary - add:
public bool Skipped() => _testInfo is Xunit.Runners.TestSkippedInfo;
class TestResultSummary / public object Status - add:
_testInfo is Xunit.Runners.TestSkippedInfo ? Util.WithStyle ("Skipped", "color:orange") :
Those changes will enable the xunit script to show when a test was skipped in the results.
To test it, load the NUGET package XUnit.SkippableFact via F4, then add the test framework and finally add the tests:
[SkippableFact]
void Test_Xunit3()
{
Skip.If(true, "skipping");
Assert.True(1 + 1 == 2);
}
[SkippableTheory]
[InlineData(1)]
[InlineData(2)]
void Test_Xunit4(int x)
{
Skip.If(x==2, "skipping");
Assert.True(1 + 1 == 2);
}
Note: Those changes will also work with the plain XUnit. So adding the changes to the code does not harm.
Now if you like, continue reading the original answer (with some useful hints at the end):
Two answers pointed me into the right direction, but the descriptions haven't been complete enough, so I had to experiment a bit. To save you that time, I am describing what I did; I have now working solutions for LinqPad 5 and LinqPad 6 (and 7).
LinqPad 5 - for .NET
Based on what Tom wrote, I was able to get it working with LinqPad 5 (v5.42.01).
There are some more steps required, which aren't obvious and not explained in the accepted answer, so I'll describe what helped on my side.
First of all, you will need to use the paid version of LinqPad, because only then you are able to load NUGET packages.
To load the required packages in LinqPad, press F4. The query properties dialog opens up. In that dialog, click Add NUGET....
The NUGET dialog opens up. In the middle of the NUGET dialog, there is a search textbox. Search for xUnit.Net - once it got displayed, click Add to query, wait until it loaded, then click on Add namespaces. Then do the same for Xunit.Runner.LinqPad.
Then close the NUGET dialog, but keep the query properties open. You need to to there to the Advanced tab: Enable (tick-mark) "Copy all non-framework references to a single local folder." Now you can close the query properties dialog.
Import the following example into the query editor (C# Program mode):
void Main()
{
// Press F4, go to Advanced, then
// tick-mark "Copy all non-framework references to a single local folder"
var me = Assembly.GetExecutingAssembly();
var result = Xunit.Runner.LinqPad.XunitRunner.Run(me);
result.Dump("Xunit runner result");
}
/// <summary>
/// This test class is there for demo purpose, so developers can
/// see how to write test methods.
/// It also verifies that XUnit itself is functioning correctly.
/// </summary>
public class A_XUnitSelfTest
{
[InlineData(2)]
[InlineData(3)]
[Theory]
public void Test_Theory(int a)
{
Assert.True(a == 2 || a == 3); // succeeds
}
[Fact]
public void Test_Fact()
{
Assert.False(1 == 0); // succeeds
}
}
Run it and you will see the output of the test runner.
Running 3 of 3 tests...
Finished: 3 tests in 0,003s (0 failed, 0 skipped)
Modify the test to see how it looks like if a test fails by changing the assert in the Test_Fact() to Assert.False(1 == 1);, then run it again. It should show this time:
Running 3 of 3 tests...
[FAIL] UserQuery+A_XUnitSelfTest.Test_Fact: Assert.False() Failure
Expected: False
Actual: True
at Xunit.Assert.False(Nullable`1 condition, String userMessage)
at Xunit.Assert.False(Boolean condition)
at UserQuery.A_XUnitSelfTest.Test_Fact() in C:\Users...\AppData\Local\Temp\LINQPad5_oyxxqxbu\query_mxsmky.cs:line 62
Finished: 3 tests in 0,005s (1 failed, 0 skipped)
LinqPad 6 - for .NET Core
LinqPad 6 is different, because it is based on .NET Core and hence does require different libraries.
Start with this:
void Main()
{
// Press F4, go to Advanced, then
// tick-mark "Copy all non-framework references to a single local folder"
var me = Assembly.GetExecutingAssembly();
var result = Xunit.Runner.LinqPad.XunitRunner.Run(me);
result.Dump("Xunit runner result");
}
/// <summary>
/// This test class is there for demo purpose, so developers can
/// see how to write test methods.
/// It also verifies that XUnit itself is functioning correctly.
/// </summary>
public class A_XUnitSelfTest
{
[InlineData(2)]
[InlineData(3)]
[Theory]
public void Test_Theory(int a)
{
Assert.True(a == 2 || a == 3); // succeeds
}
[Fact]
public void Test_Fact()
{
Assert.False(1 == 0); // succeeds
}
}
Then add xUnit.net, xUnit.net [Core Unit Testing Framework] and xUnit.net [Runner Utility] and all their namespaces via the F4 dialog (details see LinqPad 5 sesion) and finally copy the XUnit runner source code as mentioned by #ramiroalvarez to the end of the xUnit test example above:
XUnit runner source code
Enable "copy all nuget assemblies to a single local folder" in the F4 dialog, Advanced tab ... that should be enough, but it isn't so read on:
If you try it, it throws the exception InvalidOperationException("Please enable the shadow folder option for none-framework references (F4 -> Advanced).") in the source code.
Now I looked into the XUnit runner, and found that if you comment out 2 lines of code then it is running fine:
Original code (located in method GetTargetAssemblyFilename):
if (shadowFolder != xunitFolder
|| Directory.GetFiles(shadowFolder, "xunit.execution.*.dll").Length == 0)
{
throw new InvalidOperationException("Please enable the shadow folder option ...");
}
// ...
var targetAssembly = Path.Combine(shadowFolder, Path.GetFileName(assemblyFilename));
//Console.WriteLine($"Copy \"{ assemblyFilename }\" -> \"{ targetAssembly }\"");
File.Copy(assemblyFilename, targetAssembly, true);
Comment the lines
// ...
// throw new InvalidOperationException("Please enable the shadow folder option ...");
// ...
// File.Copy(assemblyFilename, targetAssembly, true);
and you're done! (Tested with v6.8.3 version of LinqPad 6, X64 version)
Hints:
Hint 1:
You can append the xUnit runner to your code as described, but there is a more elegant way in LinqPad 6:
Save a copy containing only the xUnit.Runner source code in the same path as your unit test files with the file name xUnit.Runner.LinqPad6.linq.
Then, add the following to the top of your test code:
Now you have cleaned up your code! Every time you create a new test, just remember to add the #load command.
Hint 2:
To be able to skip facts statically, add the following 2 attributes to the code of the test runner:
/// <summary>
/// Skip a Fact (you can override it by setting OverrideSkip=true)
/// </summary>
public class SkipFactAttribute : FactAttribute
{
/// <summary>
/// Override SkipFact: Set OverrideSkip=true to run even skipped tests
/// </summary>
public static bool OverrideSkip = false; // set to true to ignore skip
/// <summary>
/// Constructor. Used to set skip condition.
/// </summary>
public SkipFactAttribute()
{
if (!OverrideSkip) Skip = "Skipped Fact";
}
}
/// <summary>
/// Skip a Theory (you can override it by setting OverrideSkip=true)
/// </summary>
public class SkipTheoryAttribute : TheoryAttribute
{
/// <summary>
/// Override SkipTheory: Set OverrideSkip=true to run even skipped tests
/// </summary>
public static bool OverrideSkip = false; // set to true to ignore skip
/// <summary>
/// Constructor. Used to set skip condition.
/// </summary>
public SkipTheoryAttribute()
{
if (!OverrideSkip) Skip = "Skipped Theory";
}
}
This is useful, if you want to skip tests. To skip a test, simply replace [Fact] by [SkipFact] or [Theory] by [SkipTheory].
If you're busy writing a test and you want to test only that single test, set all attributes to [SkipFact] or likewise [SkipTheory], except the single one you're writing currenlty.
Then, to quickly run all the tests again from time to time - without having to change each and every single attribute - add the following to the initialization part of your test suite (see global setup for startup and teardown):
public class TestsFixture : IDisposable
{
public TestsFixture() // running once before the tests
{
// true: Ignore Skip and run all tests, false: Skip is effective
SkipFactAttribute.OverrideSkip = true;
SkipTheoryAttribute.OverrideSkip = true;
}
public void Dispose() // running once, after the tests
{
// teardown code
}
}
If you're done, restore the [Fact]/ [Theory] attributes and set the .OverrideSkip variables back to false.
NOTE: In case you want to skip facts based on a runtime condition, take a look at dynamically skipping test and theory.
More about unit testing
For some advanced topics about unit testing with xUnit, I recommend to read:
xunit tests in net core
global setup for startup and teardown
shared context
running tests in parallel
running tests in prioritized, specified order
configuring with json
configuring with xml
skipping Test and Theory // description works for TheoryAttribute too
dynamically skipping test and theory
xUnit Theory: Working With InlineData, MemberData, ClassData
If you want to use it with Visual Studio, you can find infos here.
Possible? Sort of.
This is neither a main use case of LINQPad nor of unit testing.
Regarding LINQPad, you could use an existing test runner but probably the only ones that could be integrated with LINQPad are console runners. A test runner is not a trivial program. Try Xunit.Runner.LinqPad.
As for needing to "write some tests for concepts being designed", consider that you might not be getting enough out of your unit testing workflow if you don't find them valuable enough to create a project and keep it in source control. One way to get more value is to use Behavior-Driven Development (BDD) and if you want to write the requirements in a business-readable language, try something like SpecFlow.
Thanks to asherber, xunit now works with linqpad6 (netcore).
https://github.com/asherber/Xunit.Runner.LinqPad/blob/master/Xunit.Runner.LinqPad/XunitRunner.cs
It is important within the query properties, check "copy all nuget assemblies to a single local folder" otherwise, you will have the following error "InvalidOperationException: Please enable the shadow folder option for none-framework references"
I just tried to open a LINQPad query file that tried to load the xunit package and got an error which has never happened to me in using LINQPad for years. So my answer is no.
Related
TL;DR: I'm not able to successfully use FsCheck with NUnit in C#: either:
it tells me on stdout that the test failed but the test still appears green
it tells me that it doesn't find any test to run
or I don't understand how to apply in C# the doc I read
I think a dummy but complete example would help...
(More details)
1st step: test remains green
I installed the Nuget package FsCheck.NUnit (2.10.4), and naively tried:
[NUnit.Framework.Test]
public void SomeTest()
{
// Note the subtle bug: I Reverse only once, because I want the test to fail
Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
Prop.ForAll(revRevIsOrig).QuickCheck();
}
When I run it as I would run any NUnit test, it ends up green, even though I see on stdout that
Falsifiable, after 3 tests (1 shrink) (StdGen (2129798881,296376481)):
Original:
[|-1; 0|]
Shrunk:
[|1; 0|]
2nd step: test inconclusive
So I went on, found some doc, and noticed that I should use Property instead of Test. So I changed my code to
[FsCheck.NUnit.Property] // <-- the line that changed
public void SomeTest()
{
Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
Prop.ForAll(revRevIsOrig).QuickCheck();
}
I launched the test from Visual, and it ended up with the status inconclusive. And some log was telling me:
Cannot run tests: No suitable tests found in 'xxx.exe'. Either assembly contains no tests or proper test driver has not been found
3rd step: I notice I didn't understood the doc
When I re-read the doc, I notice that it says that my test method can take argument and should return a property. I'm obviously not doing it since I return nothing.
The sad thing is that I don't understand what I'm actually supposed to do (and I'm not familiar enough with F# to understand the example below...)... (I've blindly tried some random stuff that looked they could make sense, but I never ended up with a red test)
I would really appreciate any pointer to help me get this test red!
Try using the QuickCheckThrowOnFailure function
the QuickThrowOnFailure ensures that if the test fails, an exception with the necessary information is raised so the runner know the test failed.
[Test]
public void SomeTest() {
// Note the subtle bug: I Reverse only once, because I want the test to fail
Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
Prop.ForAll(revRevIsOrig).QuickCheckThrowOnFailure();
}
The other way to use FsCheck with NUnit (from FsCheck github examples) is
[FsCheck.NUnit.Property(Verbose = true)]
public void SomeTest()
{
Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
return Prop.ForAll(revRevIsOrig);
}
But this way doesn't report you why your test fails. So the Nkosi's answer now is better but I think it will be fixed somedays.
Besides other mentioned options you can turn this test to a Property Based Test by using the Property attribute and correct return type (I've included namespaces for clarity).
Note the .ToProperty call to turn it into a Property.
[FsCheck.NUnit.Property]
public FsCheck.Property RevRev_IsOriginal(int[] xs)
{
Func<bool> revRevIsOrig = () => xs.Reverse().Reverse().SequenceEqual(xs);
return revRevIsOrig.ToProperty();
}
The framework will generate testdata via the int[] xs method parameter.
This requires nuget packages fscheck and fscheck.nunit (besides NUnit3TestAdapter and Microsoft.NET.Test.Sdk in my .NET Core 3.1 testproject).
I want to add a custom test reporter to NUnit. I already did it with NUnit2, but I now need to use NUnit3.
To implement the reporter, I need to get various events from the framework, like start, end and failure of tests.
In NUnit2 I used NUnitHook to register my EventListener and it worked pretty good.
In NUnit3 I need to use the extension point mechanism, but when I add the extension point to the project, VisualStudio (2012 ultimate) immediately fails to discover the NUnit tests.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
If I remove the ITestEventListener implementation declaration from the class, it rediscovers the tests perfectly.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener //: ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
Am I doing something wrong? is there a better way to achieve it?
You don't say where you are putting this code, but I am suspecting it's in your test assembly. If so, that's not where it belongs. NUnit engine extensions get installed into the NUnit engine, so they need to be in a separate assembly. Once you have a separate assembly, you need to tell the engine where it is. Currently, you do this by creating a file of type .addins in the same directory as the engine. (You could modify the existing file, but that introduces maintenance problems in the future)
A future release will have an easier way to install addins, but they will continue to be entirely separate from your tests.
A further problem is that you are using TypeExtensionPointAttribute. I didn't notice this originally in your code and it's probably the biggest error so I'm adding this info now.
An "ExtensionPoint" is the thing you are extending. NUnit defines ExtensionPoints, while you create Extenisons to extend them. TypeExtensionPointAttribute is used inside NUnit to define extension points. It's not used by you. You use the ExtensionAttribute to define your extension.
Your extension should be defined something like this:
[Extension(Description = "Test Reporter Extension", EngineVersion="3.4")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
You don't say what version of NUnit you are running. Test Listeners are only supported beginning with version 3.4. The EngineVersion property above is purely documentary at this point, because 3.4 is also the first version to recognize it.
There is a new writeup in the NUnit docs that may be helpful: https://github.com/nunit/docs/wiki/Writing-Engine-Extensions
Reading through https://msdn.microsoft.com/en-us/library/jj635153.aspx I have created a .RunSettings files with a few parameters similar to the example:
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
<Parameter name="webAppUserName" value="Admin" />
<Parameter name="webAppPassword" value="Password" />
</TestRunParameters>
I plan on having a .RunSettings file for each of our environments with appropriate URLs and credentials for running a CodedUI test on the specified RunSettings file's environment.
I can see that from command line to reference the Settings file I can run:
vstest.console myTestDll.dll /Settings:Local.RunSettings /Logger:trx
vstest.console myTestDll.dll /Settings:QA.RunSettings /Logger:trx
etc...
But I don't see any way that calls out how to actually utilize the TestRunParameters from within the codedUI test.
What I would like to do is set up test initializers that use the TestRunParameters to determine where to log in, and what credentials to use. Something like this:
[TestInitialize()]
public void MyTestInitialize()
{
// I'm unsure how to grab the RunSettings.TestRunParameters below
string entryUrl = ""; // TestRunParameters.webAppUrl
string userName = ""; // TestRunParameters.webAppUserName
string password = ""; // TestRunParameters.webAppPassword
LoginToPage(entryUrl, userName, password);
}
public void LoginToPage(string entryUrl, string userName, string password)
{
// Implementation
}
Information on how to reference the TestRunParameters is greatly appreciated!
EDIT
/// <summary>
/// Summary description for CodedUITest1
/// </summary>
[CodedUITest]
public class CodedUITest1
{
public static string UserName = string.Empty;
[ClassInitialize]
public static void TestClassInitialize(TestContext context)
{
UserName = context.Properties["webAppUserName"].ToString();
Console.WriteLine(UserName);
}
[TestMethod]
public void CodedUITestMethod1()
{
this.UIMap.RecordedMethod1();
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
}
// Rest of the default class - TestContext instantiation, UI map instantiation, etc
}
The exception I'm getting when running:
NullReference Exception
#williamfalconeruk I have updated my test class as above, but I am still getting the same error, any idea what I'm doing wrong?
For those that use Resharper with this issue, I discovered the fix (no need to disable Resharper):
Go to Visual Studio top menu -> Resharper -> Options
Find the Tools section, expand "Unit Testing"
Click on "MsTest". The checkbox should be on enabled, but the Test Settings file path below that may be blank. If it is, click on browse and select the runsettings file you want to use.
Click save, rebuild and try to run the tests, the parameters should now work.
Not sure why but simply selecting the Test Settings file from the Tests menu -> Test Settings does not actually work when using Resharper, so this file needs to be explicitly pointed to directly in the Resharper options.
I also came across this recently, as we wanted to move away from legacy environment variable usage. The solution provided below was suitable for our needs, but there may be a better one...
It turns out you can access these in the TestContext of a ClassInitialize method of your Test fixture. There is a Properties dictionary which has these parameters, and you could access the values here:
[ClassInitialize]
public static void TestClassinitialize(TestContext context)
{
var webAppUrl = context.Properties["webAppUrl"].ToString();
//other settings etc..then use your test settings parameters here...
}
Note: these are static so if you need access to this you may need to set up static properties to access within your Test code.
An alternative suggested is using a Data Driven Test approach.
Here's some basic info on data driven tests here which may also help:
https://msdn.microsoft.com/en-us/library/ms182527.aspx
As I said, the above solution suited our needs at a basic level.
UPDATE: see image below in response to test settings returning null...
This works for me (VS2017-pro):
namespace TestApp.Test
{
[TestClass]
public class UnitTest1
{
// This enables the runner to set the TestContext. It gets updated for each test.
public TestContext TestContext { get; set; }
[TestMethod]
public void TestMethod1()
{
// Arrange
String expectedName = "TestMethod1";
String expectedUrl = "http://localhost";
// Act
String actualName = TestContext.TestName;
// The properties are read from the .runsettings file
String actualUrl = TestContext.Properties["webAppUrl"].ToString();
// Assert
Assert.AreEqual(expectedName, actualName);
Assert.AreEqual(expectedUrl, actualUrl);
}
[TestMethod]
public void TestMethod2()
{
// Arrange
String expectedName = "TestMethod2";
// Act
String actualName = TestContext.TestName;
// Assert
Assert.AreEqual(expectedName, actualName);
}
}
}
Make sure to select the runsettings file you wish to use, here: Test -> Test Settings.
An alternative to disable Resharper is to enable MSTest support and select the test setting file on Resharper Options dialog (->Tools->Unit Testing->MsTest).
I was trying to do this exact thing as well. As many of you may know, running tests through MTM exposes some additional properties to the TestContext, including the name of the Run Settings used. I used this property as a "Foreign Key" of sorts for our test data, allowing us to specify environment URLs etc. without hardcoding them or using the incredibly lackluster "Data Driving" tools that come with out of the box testing.
Of course, there's no way to expose any run-time properties when executing tests as part of a BDT or release workflow besides what #kritner is attempting which microsoft describes HERE. However if you read the comments of that link you'll discover what you may be able to infer here:
You need to use VS 2013 R5 or VS 2015 to use this solution
It will only work for Unit Tests!
Those of us who are trying to execute UI or Load tests as part of a CI or CD workflow are completely screwed. You don't get any additional properties in testContext, even when executing a Plan/Suite with certain test configurations (not settings) created in MTM. #Adam may have been able to get this to work when running vs debugging, but that may have only worked with unit tests. Through CodedUI I've been unable to retrieve the properties without getting a NullReferenceException. Here's an example of the janky code I was using to investigate:
if (testContextInstance.Properties["__Tfs_TestConfigurationName__"] != null) //Exposed when run through MTM
{
TFSTestConfigurationName = testContextInstance.Properties["__Tfs_TestConfigurationName__"].ToString();
}
else TFSTestConfigurationName = "Local"; //Local
var configName = testContextInstance.Properties["configurationName"] ?? "No Config Found";
Trace.WriteLine("Property: " + configName);
And the XML of my .runsettings file:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<!-- Parameters used by tests at runtime. These are required as a substitute for TFS/MTM test settings.-->
<!-- File instructions: https://msdn.microsoft.com/en-us/library/jj635153.aspx#example -->
<!-- TFS instructions: https://blogs.msdn.microsoft.com/visualstudioalm/2015/09/04/supplying-run-time-parameters-to-tests/ -->
<TestRunParameters>
<Parameter name="configurationName" value="Local" />
</TestRunParameters>
</RunSettings>
And an excerpt from the .trx produced by the BDT workflow:
Property: No Config Found
For the NullReferenceException issue:
I was also facing the same issue recently and the solution to it is to have the latest update of Visual Studio 2013. Right now the latest update is Update 5. I am not sure which particular update fixes this issue. I applied Update 5 and was able to successfully access the TestRunParameters in the ClassInitialize method.
You can find the updates # https://support.microsoft.com/en-us/kb/2829760
So I had two machines, on one it was all working fine and on the other I was getting the exception. I investigated that the only difference is the Update of VS; applied it and that solved the problem. :)
With NUnit 3, I was able to find the properties in the runsettings file, using
TestContext.Parameters
So in this case it would be:
string entryUrl = TestContext.Parameters["webAppUrl"];
string username = TestContext.Parameters["webAppUserName"];
string password = TestContext.Parameters["webAppPassword"];
I was able to resolve this for Unit tests by disabling Resharper. Wish I could say the same for Coded UI tests.
Why dont you use Application settings?
you can then read them anywhere like
var yesICan= Properties.Settings.Default.IToldYou;
you can create Properties out from them, pretty much you can do a lot.
public string URL_WEBOFFICE
{
get
{
return Properties.Settings.Default.WEBOFFICE_URL.Replace("***", Properties.Settings.Default.SiteName);
}
}
In many cases I find it redundant to write a script for each little test case. How can I use Microsoft VS to write a script that can test more than one test case and report the result to each associated test case in Microsoft MTM without running each test cases separately. Say, for example, I have a yes/No/Cancel dialog that pops up and there is a test case to verify for each of the three cases. All three cases can be verified in one script. Would it be possible to associate each test case to the same script and get the results reported to each one by running the script only once?
You can use MSTest.exe or VSTest.console.exe to run TestMethods via command line. One can call MSTest.exe or VSTest.console.exe in batch file.
Assign user defined testcategory attribute to group your tests. Please refer Defining Test Categories to Group Your Tests. For Example
[TestCategory("Nightly"),
TestCategory("Weekly"),
TestCategory("ShoppingCart"),
TestMethod()]
public Void DebitTest()
{
}
[TestCategory("Nightly"),
TestCategory("Weekly"),
TestCategory("ShoppingCart"),
TestMethod()]
public Void CreditTest()
{
}
[TestCategory("Nightly"),
TestCategory("Daily"),
TestCategory("ShoppingCart"),
TestMethod()]
public Void BVTTest1()
{
}
[TestCategory("Nightly"),
TestCategory("Daily"),
TestCategory("ShoppingCart"),
TestMethod()]
public Void BVTTest2()
{
}
Running Tests via VSTest.Console.exe group by TestCategory
Vstest.console.exe myTestProject.dll /TestCaseFilter:ā€¯TestCategory=Nightly"
Running Tests by MSTest.exe group by Test Category
mstest /testcontainer:MyTestprojectName.dll /category:"Nightly"
mstest /testcontainer:MyTestprojectName.dll /category:"Daily"
Please refer MSDN Link for more command line options in this topic.
Let's say we have a short program:
namespace ConsoleTryIt
{
static class Program
{
static void Main(string[] args)
{
var sum = Add(1, 2);
}
private static int Add(int p, int p2)
{
return p + p2;
}
}
}
When create the unit test class for this class, Visual Studio create a test method with the attribute DeploymentItem. I read MSDN about this attribute but still don't get what it means.
/// <summary>
///A test for Add
///</summary>
[TestMethod()]
[DeploymentItem("ConsoleTryIt.exe")]
public void AddTest()
{
var expected = 122;
var actual = Program_Accessor.Add(1, 121);
Assert.AreEqual(expected, actual);
}
If you get the idea, please share!
Edit
Thanks everyone for your answers. So the idea is to copy the item given in the argument to the testing evironment's folder. My next question is: why does this method need this attribute while others don't?
I guess it's related to the private members on the tested class but nothing clear to me.
Please continue to discuss.
This specifies files that are required by the specific test. The test system creates a new directory where the tests are run from. With this attribute, you can make the test system copy specific files to that new directory.
Is used deploy files that are not necessary present in the Output directory to the folder used for that particular TestRun.
in the example you posted above, the test environment makes sure that "consoleTryIt.exe" is copied(and therefore present) in the test folder.
If the file is not found, the test is not even run, and a FileNotFound Exception is returned.
This means that the item is copied to the 'TestResults\Out' folder and is basically an artifact/necessary item for the test run. Thus, it is stored apart from the bin directory and does not get overwritten.
This is especially useful when running the tests in different environments (build server, no hard-coded paths...) and of course it is necessary to make the tests repeatable.
HTH.
Thomas
Ensures the files required for the test are copied over to the folder where MSTest runs its tests TestResults\Out.
Files in your solution should have "Copy Always" set for the files to be first copied to bin folder and then to MSTest's folder.
Make sure you have "Enable deployment" checked in testrunconfig.