I'm trying to use Xray's API to post the results from my unit tests. I want the method for posting the results to be ran after all my tests are finished up running (then I have a xml-file with the results I want to post).
but I'm not sure if I've understood how the mechanics work - it looks like the teardown gets executed after every single test.
What I'm trying to achieve:
Create a method that will execute ONCE after all tests are done, which should post the generated xml-file with test-results to an external API.
[TestFixture] public class ProjectEmailAgentUnitTests { private ProjectEmailAgent _emailAgent; [SetUp] public void Setup() { _emailAgent = new ProjectEmailAgent(); } [Test, Property("Requirement", "IUV-23")] [TestCase(" ", false)] [TestCase("mcp a", false)] [TestCase("mc pa", false)] [TestCase("mcpa", true)] public void isKeyWordExisting(string subject, Boolean expected) { Assert.That(_emailAgent.isKeyWordExisting(subject), Is.EqualTo(expected)); } [TearDown] public async Task TestTearDown(){ var fileName = "filename.xml"; var fileName2 = "xray.json"; var url = "https://xray.cloud.getxray.app/api/v1/import/execution/nunit/multipart"; using (var formContent = new MultipartFormDataContent("NKdKd9Yk")) { formContent.Headers.ContentType.MediaType = "multipart/form-data"; // 3. Add the filename C:\\... fileName is the path your file Stream fileStream = System.IO.File.OpenRead("C:/test/Projects/ProjectEmailAgentTest/bin/Debug/net6.0/TestResults/" fileName); formContent.Add(new StreamContent(fileStream), fileName, fileName); Stream fileStream2 = System.IO.File.OpenRead("C:/test/Projects/ProjectEmailAgentTest/" fileName2); formContent.Add(new StreamContent(fileStream2), fileName2, fileName2); using (var client = new HttpClient()) { // Bearer Token header if needed client.DefaultRequestHeaders.Add("Authorization", "Bearer " "token"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data")); try { // 4.. Execute the MultipartPostMethod var message = await client.PostAsync(url, formContent); // 5.a Receive the response Console.WriteLine(message); } catch (Exception ex) { // Do what you want if it fails. throw ex; } }
CodePudding user response:
I'll give an answer... but first this...
I think it's actually a mistake to use code in your tests to manage the reporting of the tests. That's because NUnit, like most test frameworks, works really hard to segregate the tests from the context in which they are run. However, as you have shown, it can be made to work. What's questionable is how long it will keep working. Given that the NUnit folks are trying hard to isolate tests from their context, suppose they make improvements in the next release - what happens then? Those improvements would appear to you as bugs, because you are relying on running a certain lack of isolation.
However, with the current state of the nunti framework, if you want to do this,
use an assembly-level SetUpFixture
. Specifically...
- Create a class in the global namespace, i.e. outside all namespaces.
- Decorate that class with
[SetUpFixture]
- Within the class, add a
public void
method and decorate it with[OneTimeTearDown]
.
Now you have a class that looks something like this...
[SetUpFixture]
public static class MySetUpFixture
{
[OneTimeSetUp]
public static void AfterAllTestsRun()
{
// Your code here
}
}
As stated above place this outside of any namespaces. I made my class static. It doesn't have to be but do not let any of your test fixtures inherit from it. You'll confuse NUnit if you do.
On the other hand, if you want to do this outside of your test code, write a program to read the TestResult file and create the necessary email. It's not that hard to do.