Way to eliminate pre-processor commands - c#

I need a way to show this C# 3.0 code:
[TestMethod]
#if NUNIT
[Moled]
#else
[HostType("Moles")]
#endif
public void TestSomething()
With out using/needing the pre-processor commands on each method.
Is this possible?
Talking with a co-worker, we theorized that there may be a way to create an attribute class that has 2 constructors (one with zero params and one with 1 string). Then in the top of the file we do our conditional there like this:
#if NUNIT
Moled = MyNamespace.MyNewAttribute;
#else
HostType = MyNamespace.MyNewAttribute;
#endif
The MyNewAttribute class would be setup to do nothing, so that I can compile with this:
[TestMethod]
[Moled]
[HostType("Moles")]
public void TestSomething()
Would this work? How would I write this class?

Your updated question provides an interesting and (in my opinion) viable solution.
All you need to do to finish it is to declare MyNewAttribute, which should be simple:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class MyNewAttribute : Attribute
{
public MyNewAttribute() { }
public MyNewAttribute(string dummy) { }
}
In your #if trick, you will have to use the full class names:
#if NUNIT
using MoledAttribute = MyNamespace.MyNewAttribute;
#else
using HostTypeAttribute = MyNamespace.MyNewAttribute;
#endif
Note: I don’t know which way around these should be — your question contradicts itself on this. Remember you need to redefine the one that you want to disable, not the one you want to enable.
Also, these using statements need to be first within the namespace, before all type declarations. I tried this and it works even if MyNewAttribute is declared further down in the same file.
Since this is quite an unusual trick, I strongly recommend to put an explanatory comment on the #if construct so that future readers of your code can understand what it means, why it’s there, and how it works.
By the way, with custom attribute names as short as these, and with few or no constructor arguments, personally I find it more readable to put them in one line:
[TestMethod, Moled, HostType("Moles")]
public void TestSomething()

I don't see why you need aliases at all. Just do this in one single file:
#if NUNIT
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class HostTypeAttribute : Attribute
{
public HostTypeAttribute(string dummy) { }
}
#else
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class MoledAttribute : Attribute
{
public MoledAttribute() { }
}
#endif
Then you can use both, in any file, with no preprocessor defines anywhere except here.

You are close to the right track. You just need to create a dummy attribute class that can take the place of the attributes that you are trying to switch:
public sealed class DummyAttribute : Attribute
{
public DummyAttribute()
{}
pulic DummyAttribute(string dummy)
{}
}
The two constructors are necessary because one of the attributes that you are trying to replace accepts a string as a parameter. Setting up the dummy constructors allows you to ignore the actual behavior of the attributes that you are replacing.
Then your preprocessor block at the top of the file should look something like this:
#if !NUNIT
using Moled = MyNameSpace.DummyAttribute;
#else
using HostType = MyNameSpace.DummyAttribute;
#endif

Sure, split it into two files:
File1:
[TestMethod]
[Moled]
public void TestSomething()
File2:
[TestMethod]
[HostType("Moles")]
public void TestSomething()
Use whichever file is appropriate.
UPDATE:
Ah, I think I finally understand what you're after.
You don't really want to "eliminate the preprocessor directives" as your original question requested, what you actually want to do is unify the attributes on your methods based on a preprocessor directive.
Yes, that can be done via the magic of a using class alias!
You rename the two attribute classes you're interested in swapping to the same name like this:
#if NUNIT
using MyAttrib = System.Diagnostics.ConditionalAttribute;
#else
using MyAttrib = System.ObsoleteAttribute;
#endif
And then you decorate all your methods like this:
[MyAttrib( "attrib arg" )]
public void TestSomething()
I've done the exact same thing myself for when a project was going to be unit tested via the Microsoft way but not until we had the version of Visual Studio that supported it.

Related

c# use base type generic parameter type name in derived class [duplicate]

I want to create an alias for a class name. The following syntax would be perfect:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
but it won't compile.
Example
Note This example is provided for convenience only. Don't try to solve this particular problem by suggesting changing the design of the entire system. The presence, or lack, of this example doesn't change the original question.
Some existing code depends on the presence of a static class:
public static class ColorScheme
{
...
}
This color scheme is the Outlook 2003 color scheme. i want to introduce an Outlook 2007 color scheme, while retaining the Outlook 2003 color scheme:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
But i'm still faced with the fact that the code depends on the presence of a static class called ColorScheme. My first thought was to create a ColorScheme class that I will inherit from either Outlook2003 or Outlook2007:
public static class ColorScheme : Outlook2007ColorScheme
{
}
but you cannot inherit from a static class.
My next thought was to create the static ColorScheme class, but make Outlook2003ColorScheme and Outlook2007ColorScheme classes non-static. Then a static variable in the static ColorScheme class can point to either "true" color scheme:
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
but that would require me to convert a class composed entirly of readonly static Colors into overridable properties, and then my ColorScheme class would need to have the 30 different property getters thunk down into the contained object.
That's just too much typing.
So my next thought was to alias the class:
public static ColorScheme = Outlook2007ColorScheme;
But that doesn't compile.
How can I alias a static class into another name?
Update: Can someone please add the answer "You cannot do this in C#", so I can mark that as the accepted answer. Anyone else wanting the answer to the same question will find this question, the accepted answer, and a number of workarounds that might, or might not, be useful.
I just want to close this question out.
You can’t. The next best thing you can do is have using declarations in the files that use the class.
For example, you could rewrite the dependent code using an import alias (as a quasi-typedef substitute):
using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Unfortunately this needs to go into every scope/file that uses the name.
I therefore don't know if this is practical in your case.
You can make an alias for your class by adding this line of code:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
You cannot alias a class name in C#.
There are things you can do that are not aliasing a class name in C#.
But to answer the original question: you cannot alias a class name in C#.
Update: People are confused why using doesn't work. Example:
Form1.cs
private void button1_Click(object sender, EventArgs e)
{
this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
ColorScheme.cs
class ColorScheme
{
public static Color ApplyColorScheme(Color c) { ... }
}
And everything works. Now i want to create a new class, and alias ColorScheme to it (so that no code needs to be modified):
ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme;
class Outlook2007ColorScheme
{
public static Color ApplyColorScheme(Color c) { ... }
}
Ohh, i'm sorry. This code doesn't compile:
My question was how to alias a class in C#. It cannot be done. There are things i can do that are not aliasing a class name in C#:
change everyone who depends on ColorScheme to using ColorScheme instead (code change workaround because i cannot alias)
change everyone who depends on ColorScheme to use a factory pattern them a polymorphic class or interface (code change workaround because i cannot alias)
But these workarounds involve breaking existing code: not an option.
If people depend on the presence of a ColorScheme class, i have to actually copy/paste a ColorScheme class.
In other words: i cannot alias a class name in C#.
This contrasts with other object oriented languages, where i could define the alias:
ColorScheme = Outlook2007ColorScheme
and i'd be done.
You want a (Factory|Singleton), depending on your requirements. The premise is to make it so that the client code doesn't have to know which color scheme it is getting. If the color scheme should be application wide, a singleton should be fine. If you may use a different scheme in different circumstances, a Factory pattern is probably the way to go. Either way, when the color scheme needs to change, the code only has to be changed in one place.
public interface ColorScheme {
Color TitleBar { get; }
Color Background{ get; }
...
}
public static class ColorSchemeFactory {
private static ColorScheme scheme = new Outlook2007ColorScheme();
public static ColorScheme GetColorScheme() { //Add applicable arguments
return scheme;
}
}
public class Outlook2003ColorScheme: ColorScheme {
public Color TitleBar {
get { return Color.LightBlue; }
}
public Color Background {
get { return Color.Gray; }
}
}
public class Outlook2007ColorScheme: ColorScheme {
public Color TitleBar {
get { return Color.Blue; }
}
public Color Background {
get { return Color.White; }
}
}
try this:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
I'm adding this comment for users finding this long after OP accepted their "answer".
Aliasing in C# works by specifying the class name using it's fully qualified namespace. One defined, the alias name can be used within it's scope.
Example.
using aliasClass = Fully.Qualified.Namespace.Example;
//Example being the class in the Fully.Qualified.Namespace
public class Test{
public void Test_Function(){
aliasClass.DoStuff();
//aliasClass here representing the Example class thus aliasing
//aliasClass will be in scope for all code in my Test.cs file
}
}
Apologies for the quickly typed code but hopefully it explains how this should be implemented so that users aren't mislead into believing it cannot be done in C#.
Aliasing the way that you would like to do it will not work in C#. This is because aliasing is done through the using directive, which is limited to the file/namespace in question. If you have 50 files that use the old class name, that will mean 50 places to update.
That said, I think there is an easy solution to make your code change as minimal as possible. Make the ColorScheme class a facade for your calls to the actual classes with the implementation, and use the using in that file to determine which ColorScheme you use.
In other words, do this:
using CurrentColorScheme = Outlook2007ColorScheme;
public static class ColorScheme
{
public static Color ApplyColorScheme(Color c)
{
return CurrentColorScheme.ApplyColorScheme(c);
}
public static Something DoSomethingElse(Param a, Param b)
{
return CurrentColorScheme.DoSomethingElse(a, b);
}
}
Then in your code behind, change nothing:
private void button1_Click(object sender, EventArgs e)
{
this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
You can then update the values of ColorScheme by updating one line of code (using CurrentColorScheme = Outlook2008ColorScheme;).
A couple concerns here:
Every new method or property definition will then need to be added in two places, to the ColorScheme class and to the Outlook2007ColorScheme class. This is extra work, but if this is true legacy code, it shouldn't be a frequent occurence. As a bonus, the code in ColorScheme is so simple that any possible bug is very obvious.
This use of static classes doesn't seem natural to me; I probably would try to refactor the legacy code to do this differently, but I understand too that your situation may not allow that.
If you already have a ColorScheme class that you're replacing, this approach and any other could be a problem. I would advise that you rename that class to something like ColorSchemeOld, and then access it through using CurrentColorScheme = ColorSchemeOld;.
I suppose you can always inherit from the base class with nothing added
public class Child : MyReallyReallyLongNamedClass {}
UPDATE
But if you have the capability of refactoring the class itself: A class name is usually unnecessarily long due to lack of namespaces.
If you see cases as ApiLoginUser, DataBaseUser, WebPortalLoginUser, is usually indication of lack of namespace due the fear that the name User might conflict.
In this case however, you can use namespace alias ,as it has been pointed out in above posts
using LoginApi = MyCompany.Api.Login;
using AuthDB = MyCompany.DataBase.Auth;
using ViewModels = MyCompany.BananasPortal.Models;
// ...
AuthDB.User dbUser;
using ( var ctxt = new AuthDB.AuthContext() )
{
dbUser = ctxt.Users.Find(userId);
}
var apiUser = new LoginApi.Models.User {
Username = dbUser.EmailAddess,
Password = "*****"
};
LoginApi.UserSession apiUserSession = await LoginApi.Login(apiUser);
var vm = new ViewModels.User(apiUserSession.User.Details);
return View(vm);
Note how the class names are all User, but in different namespaces. Quoting PEP-20: Zen of Python:
Namespaces are one honking great idea -- let's do more of those!
Hope this helps
Is it possible to change to using an interface?
Perhaps you could create an IColorScheme interface that all of the classes implement?
This would work well with the factory pattern as shown by Chris Marasti-Georg
It's a very late partial answer - but if you define the same class 'ColorScheme', in the same namespace 'Outlook', but in separate assemblies, one called Outlook2003 and the other Outlook2007, then all you need to do is reference the appropriate assembly.
The best way I've found to simulate alias in C# is inheritance.
Create a new class that inherits from the original class:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName
: LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{
}
The only thing that you would need to be careful is the constructor. You need to provide a a constructor for MyName class.
public class MyName
: LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{
public MyName(T1 param1, T2 param2) : base(param1, param2) {}
}
In this example I'm using T1 and T2 as generic types, since I don't know the constructor for your LongClassNameOrOneThatContainsVersionOrDomainSpecificName class.
Beware, though, that this is not alias. Doing this to you application might run into some issues or problems. You might need to create some extra code to check for types, or even overload some operators.

NUnit extending ICommandWrapper How do I wrap a TestCase?

I tried extending extending ICommandWrapper, following this article: https://www.skyrise.tech/blog/tech/extending-nunit-3-with-command-wrappers/. I figured out that I can also extend TestAttribute and it just works, then I tried extending TestCaseAttribute:
[AttributeUsage(AttributeTargets.Method), AllowMultiple = true]
public class MyTestCaseAttribute : TestCaseAttribute, IWrapSetUpTearDown
{
private object[] _args;
public MyTestCaseAttribute(params object[] args) : base(args)
{
_args = args;
}
public TestCommand Wrap(TestCommand command)
{
return new MyTestCommand(command, _args);
}
}
MyTestCommand extends DelegatingTestCommand, just like in the article.
The problem is, if I add multiple MyTestCaseAttributes to a test method, the test method gets wrapped by MyTestCommand.Execute's code multiple times.
[EDIT] Example:
Suppose MyTestCommand looks like this:
public abstract class MyCommandDecorator : DelegatingTestCommand
{
public override TestResult Execute(TestExecutionContext context)
private object[] _testCaseArgs;
protected TestCommandDecorator(TestCommand innerCommand, params object[] args) : base(innerCommand)
{
_testCaseArgs = args;
}
public override TestResult Execute(TestExecutionContext context)
{
DoSomething(_testCaseArgs);
return context.CurrentResult = innerCommand.Execute(context);
}
}
Suppose I decorate a test method with two [MyTestCase] attributes:
[MyTestCase(1)]
[MyTestCase(2)]
public void MyTest(int foo)
{
//...
}
The desired behaviour is something like:
DoSomething(1);
MyTest(1);
DoSomething(2);
MyTest(2);
But actual behaviour is:
DoSomething(2)
DoSomething(1)
MyTest(1)
DoSomething(2)
DoSomething(1)
MyTest(1)
The key to your problem is this... C# allows you to decorate a method or a class with an attribute. But an individual test case doesn't exist outside of NUnit - there is no C# equivalent - so you can't decorate it.
IOW your two Attributes apply to the method and cause NUnit to use that method to generate two test cases. However, your attributes also implement ICommandWrapper, which causes NUnit to wrap any test cases it generates. One part of NUnit is looking for test cases to create another part is looking for attributes to wrap test cases. Those two parts are entirely separated.
That's why NUnit uses properties on the test case method to indicate things like Ignoring the case. It can't use an attribute because an attribute would apply to every test case generated by that method.
Hopefully, that explains what's happening.
To get past the problem, your command wrapper should only apply itself to a test that was generated by that particular instance of the attribute. That means you have to get involved in the creation of the test, at least to the extent that your attribute remembers the reference to the test it created. This is a bit complicated, but you should look at the code for TestCaseAttribute to see how the test case is created.
Figured it out.
Instead of extending TestCaseAttribute, I can extend TestAttribute and obtain the arguments to pass to the wrapper class from standard TestCaseAttributes using command.Test.Arguments.
[AttributeUsage(AttributeTargets.Method), AllowMultiple = true]
public class MyTestAttribute : TestAttribute, IWrapSetUpTearDown
{
public TestCommand Wrap(TestCommand command)
{
return new MyTestCommand(command, command.Test.Arguments);
}
}
[TestCase(1)]
[TestCase(2)]
[MyTest]
public void MyTest(int foo)
{
//...
}

Anded multiple tags do not work as expected in specflow

I have the following hook in my test project:
[AfterScenario]
[Scope(Tag = "Tag1"), Scope(Tag = "Tag2")]
public static void AfterScenarioMethod()
{
}
Based on the SpecFlow documentation, I should expect to enter AfterFeatureMethod() only if the ScenarioContext.Current.ScenarioInfo.Tags includes both of the required tags. However, the method is executed even when only Tag1 is available.
Am I missing something here?
First AfterScenario is not static.
If you define multiple properties on one attribute, they are combined with AND.
If you have multiple attributes, they are combined with OR.
From documentation: https://specflow.org/documentation/Scoped-Bindings/
If multiple [Scope] attributes are defined for the same method or class, the attributes are combined with OR, i.e. at least one of the [Scope] attributes needs to match.
To check for multiple tags you have to do following:
[Binding]
public class Bindings
{
private ScenarioContext _scenarioContext;
public Bindings(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}
[AfterScenario]
public static void AfterScenarioMethod()
{
if (_scenarioContext.ScenarioInfo.Tags.Contains("Tag1") &&
_scenarioContext.ScenarioInfo.Tags.Contains("Tag2") {
//do you stuff
}
}
}
Code is written from memory, I didn't tried it out.

Is there an attribute that is effectively the opposite of ObsoleteAttribute?

In other words, is there an Attribute that marks a segment of code as not too old, but too new and therefore not quite ready for widespread use?
If I'd have to create a custom Attribute to accomplish this, that's fine. I just wanted to make sure first.
No, there's nothing standardized around this. You might want to consider just not exposing code like that though - or only exposing it in beta builds etc.
Not an attribute, but there are preprocessor directives (https://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx) which we can use to mark a region of code as "too new" to run. Basically you can define a flag to indicate that piece of code is ready.
Here is an example:
#define FOREST_CAN_RUN
//undef FOREST_CAN_RUN --> disable that feature
using System;
namespace Test
{
public class Forest
{
public void Run()
{
#if FOREST_CAN_RUN
Console.Write("Run Forest, Run !");
#else
Console.Write("Sorry, Jenny");
#endif
}
}
public class Program
{
static void Main(string[] args)
{
Forest f= new Forest ();
f.Run();
}
}
}

Skipping a whole test class in xUnit.net

Is it possible to skip all tests from a specific class like in NUnit
[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
No - there is no such facility at present, and the last time it was requested it was considered too low value to add,
One quick way of achieving the effect in xUnit is to comment out the public - private classes are not reflected over (obviously it won't appear on the skip list that way though).
UPDATE: Another way is to put a TraitAttribute on the class and then (assuming you're using the xunit.console runner) filter it out by running with /-trait traitName. (e.g. you can achieve ExplicitAttribute, some aspects of the BDD frameworky technique of Pending tests and similar semantics that way - of course the big problem is they don't show up in any reports when using any of these filtering techniques)
UPDATE 2: You can do
const string skip = "Class X disabled";
[Fact(Skip=skip)]
void Test() {}
Then you can change to to const string skip = null to undo the skip. The (dis)advantage of this is that the test is still shown as a Skipped test in the test list, generally with a reason included in the test run report (vs making it private which makes it likely to be forgotten)
Here is my hack to avoid error xUnit1000: Test classes must be public (checked on single Fact, I think Theories can be hacked this way, too).
// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!
// Uncomment to disable tests
internal class FactSwitch : Attribute { }
public class MyTests
{
[FactSwitch]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
(3 years later)
While searching for the same solution I found there are better ways to do the same.
Let's rewrite the example above in a way Ruben Bartelink suggested (continuation of his idea).
public class MyTests
{
//const string SkipOrNot = null; // Run all tests
const string SkipOrNot = "reason"; // Skip all tests
[Fact(Skip = SkipOrNot)]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
Nathan Cooper suggested a good improvement for my idea:
public class MyTests
{
// Uncomment to disable tests
//private class FactAttribute : Attribute { }
[Fact]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
So I like both ideas from Ruben and Nathan. There is a subtle difference between using Skip="something" (Ruben) and not using Skip at all. Using "Skip" will put all your tests in a "Skipped tests" warning zone, while "FactAttribute : Attribute" will hide them.
I've found yet another way of temporary disabling entire class without compiler warning.
Disabled:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}
to enable move the /* one line up (i.e. using alt+up):
/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}
Note that using full namespace path for SupressMessage does not mess up with your usings.
You need to set the your class access level as as internal and surpress message as #Miq did:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
You can create LocalOnlyFactAttribute
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => base.Skip = value; }
}
As far as I know, the simplest way to dynamically skip a whole xUnit test class at runtime is to use the TestFrameworkAttribute at the assembly level, to point to a class that implements the ITestFramework interface (or inherits from XunitTestFramework, which is simpler) and which overrides the CreateDiscoverer() method to return another class, that implements the ITestFrameworkDiscoverer interface (or inherits from XunitTestFrameworkDiscoverer, which is simpler), where you can finally override the IsValidTestClass() method, to decide whether a class should be skipped or not.
Here is some sample code:
[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]
namespace MyNamespace.Xunit
{
public class MyTestFramework : XunitTestFramework
{
public MyTestFramework(IMessageSink messageSink)
: base(messageSink)
{
}
protected override ITestFrameworkDiscoverer CreateDiscoverer(
IAssemblyInfo assemblyInfo)
=> new MyTestFrameworkDiscoverer(
assemblyInfo,
SourceInformationProvider,
DiagnosticMessageSink);
}
public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
{
public MyTestFrameworkDiscoverer(
IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IMessageSink diagnosticMessageSink,
IXunitTestCollectionFactory collectionFactory = null)
: base(
assemblyInfo,
sourceProvider,
diagnosticMessageSink,
collectionFactory)
{
}
protected override bool IsValidTestClass(ITypeInfo type)
=> base.IsValidTestClass(type) &&
FilterType(type);
protected virtual bool FilterType(ITypeInfo type)
{
// Insert your custom filter conditions here.
return true;
}
}
}
Tested with xUnit 2.4.1.
We are using it in Pomelo.EntityFrameworkCore.MySql (see AssemblyInfo.cs and MySqlXunitTestFrameworkDiscoverer.cs) (a bit more complex than the sample code here).
You could achieve this through a custom ITestClassCommand.
See http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html
Here's another hack that requires minimal changes to code
using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
Any compatible attribute can be used for the replacement.
If you also use the InlineDataAttribute then you'll need to define a replacement as I don't think there's an existing compatible attribute.
using InlineDataAttribute = DummyDataAttribute;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
public DummyDataAttribute(params object[] data)
{
}
}
Adding a reason almost after one year after the initial question. I have a set of tests which are calling real server apis, and I would like to run then on demand. With nUnit, it has Ignore attribute : with that set, test runner will skip those tests, but I can still manually run it.
xUnit has no such feature. The nearest one is setting such a class level attribute, and comment it out when I want to run it.
Consider creating LocalOnlyFactAttribute, which can be reused across multiple test files.
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => this.Skip = value; }
}

Categories