In previous versions of nunit.framework (e.g. 3.7.1.0), you could add properties to TestContext.Test Like this in C#:
TestContext.CurrentContext.Test.Properties.Add("NewProperty", "some value");
I updated to a newer version (e.g. 3.10.1), and that is no longer an option?
I used to pack it with extra information about the test run during runtime. And then when my base class [TearDown] method ran, I would do extra processing for those properties.
Has that moved and/or is there another way to do that?
A quick answer from 2020.
It is still possible to set test property but using Property attribute: https://github.com/nunit/docs/wiki/Property-Attribute
The property value is still accessible via TestContext, see this example for more details
Related
Let's say I want to write a library and it should invoke OptionalLibClass.Run() if such method is available. However the assembly is big (like SkiaSharp) so I do not want to include it with my library, in case the end developer only need other features.
I know it's possible to use System.Reflection but you lose the benefit of Intellisense and static typing as well as getting a performance hit (though pretty minor IMO, usually it's not a problem).
Expectation:
Add OptionalLib as a reference. Still it should be optional: user should not have to install OptionalLib if they install MyLib from Nuget for example.
Write the following code in the library:
using OptionalLib; // .NET should be able to see this namespace
// ...
if (OptionalLibAvailable()) // How to implement OptionalLibAvailable?
{
OptionalLibClass.Run() // IntelliSense should be able to show me OptionalLibClass
}
End user (developer) doesn't need to do anything beside referring to OptionalLib if they want to.
Note that there may be multiple optional libs.
Possible Workaround:
While typing the questions, I thought of a few solutions though they are not as simple as I would like:
Make an interface IOptionalRun for example. However, end user has to provide their own implementation.
Following above workaround, add a separate MyLib (without OptionalLib) and MyLib.OptionalLib (with OptionalLib) that provides an IOptionalRun implementation. I think this is the best workaround so far and the closest to my expectation but we still need 2 separate assemblies and the user has to register the interface somehow. This workaround has a problem when there are multiple optional libraries and we want users to have any of their combinations (for example: do A if A is available, B if B is available but C if both A and B are available)
Using dynamic: the worst workaround IMO. Technically a shorter System.Reflection solution but still have all its problem.
EDIT: After reading my question again, turn out a solution will probably be the answer to: how to pack/create a Nuget package for a project that contains OptionalLib but it should not be in the dependency list (and don't pack that dll when packing the Nuget package). OptionalLibAvailable can just be a Reflection call to see if OptionalLib assembly is loaded in the current AppDomain.
Edit the properties of that big assembly reference, in the properties window, there is a property Private Assets, set its value to All, then repack your library, you will find that reference has gone from the .nuspec file.
I want to force the usage of an attribute, if another attribute is used.
If a special 3rd party attribute is attached to a property, this attribute also needs to be given to a property.
Is there any possibility of doing this?
For example:
[Some3rdPartyAttribute("...")]
[RequiredAttribute("...)]
public bool Example{get; set;}
should bring no compile error,
[Some3rdPartyAttribute("...")]
public bool Example{get; set;}
should bring a compile error or warning.
The attribute itself is definded like the example from http://msdn.microsoft.com/en-US/library/z919e8tw(v=vs.80).aspx itself . But how to force the usage of the attribute if another attribute is used?
Unfortunately you cannot generate custom compiler warnings from attributes. Some attributes like System.ObsoleteAttribute will generate a warning or error, but this is hard-coded into the C# compiler. You should find another solution to your problem, maybe letting Some3rdPartyAttribute inherit from RequiredAttribute?
Otherwise you have to change the compiler.
Another option is using some AOP techniques. Like for example:
PostSharp.
Using it you can at compilation analyze yur code and emit a error if some condition does not sutisfies your requirements.
For concrete example on attributes, can have a look on :
PostSharp 2.1: Reflecting Custom Attributes
You can make a console app, that will iterate trough all types in your assembly trough reflection, check if the rule is satisfied and return 0 if it is, and some other error code and output error if the rule is broken.
Then make this console app run as post-build task.
As far as I know, there is no way to check for attributes at compile time.
I recently needed to enforce something similar (all classes derived from a certain base class need certain attributes). I ended up putting a manual check (with [Conditional("DEBUG")]) using reflection into the constructor of the base class. This way, whenever someone creates an instance of a class with missing attributes, they get an exception. But this might not be applicable in your case, if your classes do not all derive from the same class.
You could write some code that runs on application start which uses reflection and would then throw runtime exceptions if an attribute was used without the proper match but I believe that's as far as you can go and personally I wouldn't consider that a good approach as you would need to run the application once to make sure it complies with your rules.
Also, take a look at PostSharp which may help you.
How about using #warning + Unit testing? In this way, whenever you run Unit tests, an warning will be generated (or you could just use Debug.Fail instead of #warning)
I need to use a iOS build setting in Unity3d that strips unused classes from bytecode but as it uses static analysis to discover which to remove- so any classes resolved through reflection will not be excluded from removal unless explicitly added to an exclusion list. I managed to remove all uses of reflection in my own code, but Mono itself seems to use a reflection based configuration to do a bunch of stuff and I've already added about a dozen classes to the exclusion list but now I'm to the point where exceptions are not giving any clues as to what class needs to be excluded for them to work.
My question is, is it possible to get a precise list of all the classes (with source assembly and namespace) resolved through reflection throughout every assembly that the application uses, and how would you go about it? I have Visual Studio 2012 and while I know it has powerful debugging tools I don't know how I would use them to this end.
Thanks.
The short version
You can't as there is no way to find all lookups via reflection using static analysis.
The long version
Just think of the following example: I write code that selects a class depending on user input, e.g. in pseudo code:
string action = ... ; // get some user input here, e.g. "Fire"
string clazz = "Do" + action;
var obj = Activator.CreateInstance("MyActions", clazz);
As you can see the actual full class name is not occuring anywhere in the code. So you would need to execute the code in every possible way to find out which values the clazz variable could assume. Therefore you cannot find out which classes this code would access via reflection.
Further Questions
What exact API from Mono are you using and what kind of exceptions are you getting? Maybe there is some alternative that could be used for your purpose.
I remember something like 'explicit', and google says that nunit has such attribute.
Does Microsoft.VisualStudio.TestTools.UnitTesting provide something like this?
The MSTest tools does not explicitly support this type of behavior at an attribute level. At the attribute level you can either enable a test via the TestMethod attribute or completely disable it with the Ignore attribute. Once the Ignore attribute is added, mstest will not run the test until it is removed. You cannot override this behavior via the UI.
What you can do though is disable the test via the property page. Open up the test list editor, select the test you want and hit F4 to bring up the property page. Set the Test Enabled property to false. The test will now not run until you re-enable it through the property page. It's not exactly what you're looking for but likely the closest equivalent.
You can create a "Run Manually" category for your tests using the Category attribute, and then exclude that category from your tests in the GUI. These tests will be grayed out, and you can put them back in whenever you want. I do this often for slow-running tests.
I haven't used it, and it looks pretty old (Mar 2008), but I see that TestListGenerator claims to auto-generate Test Lists based on attributes you set on your tests. If it works, this would effectively provide Categories for MS Test. While not the same as Explicit, it may let you achieve what you want.
Question in the title.
I'd like to avoid recompiling since the source code I'm modifying is third party and I'd like to use the original binaries where possible, and replace only the assembly which contains the class I modified. But I'm not sure if this is a safe thing to do. In C++ for example this is definitely a bad idea.
No.
The assemblies that reference your library refer to methods and types using (some form of) name, so as long as you don't change the names of public types and methods (used by other assemblies), you don't need to recompile any of the assemblies - they will work with the updated version of the library.
In most cases Tomas answer is correct, but there are some cases where it is not true:
When using strong naming (signing) change of a single character leads to a new signature, thous leading to a new strong name.
Setting in your project references for your assembly the property Specific Version to true and changing the version number manually or automatically in AssemblyInfo.cs
No. All other assemblies will automatically work with the newly updated library.