Reputation: 6963
I developed a CustomAttribute class for my Test Project called like this:
[Test, CustomAttribute]
It's job is to get the current Test name upon entry, using this code:
var testName = TestContext.CurrentContex.Test.Name
Every time it's called there is at least one instance of this string:
AdHockTestMethod
I never knew why; but I put in a filter to ignore it as that is not the Test Name I need. (It appears to be an NUnit internals thing).
My Test Code is simply something like this:
[TestFixture]
public class TestClassName: BaseClass {
[Test, CustomAttribue]
public async Task TestName(){
}
// do something asynchronous here
}
Upvotes: 0
Views: 383
Reputation: 13736
NUnit creates an AdhocTestContext when you try to access the test context before one has been created. The name of the (non-existent) test method in the adhoc context is AdHocTestMethod. I suspect that's what you are getting.
The adhoc context is helpful in a particular scenario, which is why we implemented it. However, it's a very rare scenario and it turns out that the adhoc context can be quite confusing in more normal cases.
You haven't posted any code to indicate where in your code you are accessing the TestContext but the most common error is to try to access it in a TestCaseSource method, which is not called during the execution of your test but a century or so (in computer time) before. :-)
Hopefully my guess helps but if not, please edit the question to include code that shows where you are creating and using a TestContext.
UPDATE:
You posted the code for your attribute as a separate question, and it indicates you are creating the adhoc TestContext in the attribute constructor. (As already explained, it is created automatically as a side-effect of your trying to access it.)
Your comment also mentions NUnit "calling" the attribute. That's a misconception. NUnit merely examines the attribute. It is created by the runtime when it is needed - that's how C# attributes work. Because of this, you should never do anything in the constructor of an attribute, which depends on any outside event... in this case the creation of a proper test context. Normally, one merely saves any constructor arguments for use later.
The fact that you have made this work in your particular case is, unfortunately, just luck. Your code is not doing anything to trigger a crash but later additions to the class it calls could do so. You would be better off to work with both NUnit and the runtime rather than against them. :-)
If you want the attribute to be "active" ... that is, to do something rather than just hold data, you should use one of NUnit's extensibility interfaces. Using these interfaces is the only way to make NUnit actually call into your code in the attribute. The interfaces for custom attributes are extensively documented at https://docs.nunit.org/articles/nunit/extending-nunit/Custom-Attributes.html.
Upvotes: 1
Reputation: 6963
The root cause turned out to be the async method declaration shown above. As soon as I removed that part and used Task.Run with Async (inside the method) everything worked. The updated code looked like this:
[Test, CustomAttribute]
public void TestName(){
Task.Run(async ()=> await doSomething());
}
TestContext.CurrentContext.Test.Name self corrected after making this change. I have no idea why this worked.
Upvotes: 0
Reputation: 6963
The CustomAttribute code looked like this:
public class CustomAttribute:Attribue{
public void CustomAttribute(){
var TestName = TestContext.CurrentContext.Test.Name;
if(TestName == "AdhocTestMethod"){
Nlog.info("Testname was AdhocTestMethod");
return;
}
Start(TestName);
}
private void Start(string TestName){
Reporter.StartTest(TestName);
}
}
Upvotes: 0