Distinguish between SpecFlow and Unit Test assembly - reflection

I have written some code that analyzes a test DLL and extracts names of tests and which tags they have using reflection.
I originally wrote it to analyze SpecFlow DLLs, but it seems to work fine for Unit Test DLLs, with a few tweaks.
Both are using MSTest (VSTest.Console.exe)
I am wondering if anyone knows how I could distinguish one type of assembly from the other, so that I can use the same code to analyze either kind of assembly, without having to specify what kind it is.
Also, if anyone knows of an existing tool to do this (Extract lists of tests from DLLs), that would be great. I am kind of feeling like I must be re-inventing the wheel here...
Sample files
Specflow DLL
Unit Test DLL
(You probably need to right-click these and unblock to be able to load them)
TLDR: How do I detect, through code, which one of these DLLs is Specflow and which is Unit Tests?

Duh, it was actually quite simple
public static bool IsSpecflowDll(Assembly assembly)
{
var references = assembly.GetReferencedAssemblies();
foreach (var reference in references)
{
if (reference.Name == "TechTalk.SpecFlow")
{
return true;
}
}
return false;
}

Related

Context Injection for parallel execution

I've managed to build some fairly simple tests that do not utilise a Page Object Model structure. The Specflow steps will just call the driver methods (such as finding an element on the page and asserting the text is correct).
The tests use NUnit as the runner and I have managed to add parallel execution by adding [Parallelizable(ParallelScope.Fixtures)] to the assembly class for the solution. This works well, but the reports that come out of NUnit are a bit messy and I'd like more useful information on them (such as screenshots).
I have since added Extent reports to the solution, whilst this works fine for when the tests run sequentially, an error message appears when running them in parallel.
The FeatureContext.Current static accessor cannot be used in multi-
threaded execution. Try injecting the feature context to the binding
class.
The Context.Current steps are used in the creation of the Extent reports. I've been reading the documentation relating to multithreading from the Specflow site, but I'm having issues understanding the concept and figuring out how I can inject FeatureContext into the binding class. I'm trying to follow this example from the site:
[Binding]
public class StepsWithScenarioContext : Steps
{
[Given(#"I put something into the context")]
public void GivenIPutSomethingIntoTheContext()
{
this.ScenarioContext.Set("test-value", "test-key");
}
}
I've also been trying to follow other examples, but I've yet to see any documentation relating how to use ScenarioContext with something like driver.findElement(By.Id("blah")).
Any help would be appreciated, I am fairly new to test automation.
You need to have a property in your Steps class:
ScenarioContext _scenarioContext.
In Constructor you adding ScenarioContext scenarioContext as a parameter and initilizing it using:
_scenarioContext = scenarioContext
Simple example:
class Steps
ScenarioContext _scenarioContext;
public Steps (ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}
Only I don't know, how it will work with inheritance.

How do I register types in assemblies that haven't been loaded with Unity?

I want to load all the types of an Interface so I can call a method on it. However, the assemblies are not referenced a compile time. They will be in the bin folder.
Is this something I can do easily with Unity?
So for example I have code sort of like:
using (var container = new UnityContainer())
{
container.RegisterType<IModule>();
var modules = container.ResolveAll(typeof(IModule));
foreach (IModule module in modules) { module.Logon(); }
Console.WriteLine("Done...");
Console.ReadLine();
}
Of course, modules resolves to nothing because the assemblies have been just dropped into the bin folder. They are not statically referenced in my current assembly.
Or, do I have to do some type of Assemblies.LoadAssembly(). I'd like this to be as dynamic as possible. I don't have to have to specify assembly names in a config file or code if possible.
Thanks in advance.
Unity does not, by itself, load any assemblies. It works off Type objects and lets the CLR load those types however it wants to.
To do dynamic discovery like you want, you'll need to write a little code to spin through the assemblies in the bin directory, load them into memory, and then spin through them looking for the types you're interested in. It's pretty trivial if you're familiar with the reflection APIs.
Here's some code you can use to loop through the bin directory and make sure every assembly there is loaded:
private static bool ForceLoadAssemblies()
{
foreach (var fileName in Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll"))
{
string assemblyName = Path.GetFileNameWithoutExtension(fileName);
if (assemblyName != null)
{
Assembly.Load(assemblyName);
}
}
return true;
}
Another option would be to look at MEF instead. MEF was explicitly designed for the dynamic discovery case, while Unity is more built around internal dependency management.

Setting up functional Tests in Flex

I'm setting up a functional test suite for an application that loads an external configuration file. Right now, I'm using flexunit's addAsync function to load it and then again to test if the contents point to services that exist and can be accessed.
The trouble with this is that having this kind of two (or more) stage method means that I'm running all of my tests in the context of one test with dozens of asserts, which seems like a kind of degenerate way to use the framework, and makes bugs harder to find. Is there a way to have something like an asynchronous setup? Is there another testing framework that handles this better?
It is pretty easy, but took me 2 days to figure it out.
The solution:
First you need to create a static var somewhere.
public static var stage:Stage
There is a FlexUnitApplication.as created by the flexunit framework, and at the onCreationComplete() function, you can set the stage to the static reference created previously:
private function onCreationComplete():void
{
var testRunner:FlexUnitTestRunnerUIAS=new FlexUnitTestRunnerUIAS();
testRunner.portNumber=8765;
this.addChild(testRunner);
testStageRef.stage=stage //***this is what I've added
testRunner.runWithFlexUnit4Runner(currentRunTestSuite(), "testsuitename");
}
and when you would access the stage in the program, you should replace it to:
if(stage==null) stage=testStageRef.stage
Assuming you're using FlexUnit 4, addAsync can be called from a [BeforeClass] method:
public class TestFixture
{
[BeforeClass]
public static function fixtureSetup() : void
{
// This static method will be called once for all the tests
// You can also use addAsync in here if your setup is asynchronous
// Any shared state should be stored in static members
}
[Test]
public function particular_value_is_configured() : void
{
// Shared state can be accessed from any test
Assert.assertEquals(staticMember.particularValue, "value");
}
}
Having said that, testing code that accesses a file is really an integration test. I'm also hardly in a position to argue against using ASMock :)
Sounds like you need to remove the dependency of loading that external file. Pretty much all Aysnchronous tests can be removed through the use of a mocking frameworks. ASMock is an awesome choice for Flex. It will allow you to fake the URLoader object and return faked configurations to run your tests against. Mocking will help with you write much better unit tests as you can mock all dependencies synchronous or asynchronous.

detect if an ASCX/ASPX is running in SharePoint?

We have a set of code that is going to be used in both standalone ASP.NET and SharePoint. I'm wondering if there's any legitimate way to write conditional code in the CS file to detect whether SharePoint is present?
It needs to be able to run in or before OnPreInit, because based on this decision we'll be switching the MasterPageFile attribute, and that needs to be done early in the page lifecycle.
I suppose I can do something like checking for the existence of a "~/layouts" directory, etc. but there must be a better way to do this. And besides, who knows - for compatibility reasons (location of images, etc) we might actually adopt the SharePoint directory structure in the ASP.NET standalone mode.
It's okay to require the Microsoft.SharePoint.DLL even if it goes mostly unused when running standalone.
Thanks!
Since you are allowed to reference Microsoft.SharePoint:
using Microsoft.SharePoint;
// ...
if (SPContext.Current == null)
// Not running in SharePoint
else
// Running in SharePoint
Edit -- alternate approach taking NullReferenceException into consideration:
bool runningInSharePoint = false;
try
{
if (SPContext.Current != null)
runningInSharePoint = true;
}
catch (NullReferenceException e)
{
// SharePoint is not present on the system
}
The above assumes that the exception you mentioned is thrown when accessing SPContext, not earlier.
I wonder if you are better off not including the SharePoint dll in your straight ASP.NET code.
If you partial/sub class the SharePoint bit and include two build targets, you should be able to tack on the extra code needed for SharePoint without turding up your ASP.NET build.

How to unit test server controls on postback?

I am trying to create my own EasyBinderDropDown that currently looks like this:
public class EasyBinderDropDown : DropDownList, ICanBindToObjectsKeyValuePair {
public void BindToProperties<TYPE_TO_BIND_TO>(IEnumerable<TYPE_TO_BIND_TO>
bindableEnumerable,
Expression<Func<TYPE_TO_BIND_TO, object>> textProperty,
Expression<Func<TYPE_TO_BIND_TO, object>> valueProperty) {...}
public bool ShowSelectionPrompt { get; set; }
public string SelectionPromptText { get; set; }
public string SelectionPromptValue { get; set; }
//...
}
Basically it is very helpful for easy binding to objects from inside code since you just do something like _dropDown.BindToProperties(myCustomers, c=>c.Name, c=>c.Id) and it works for you, also by setting ShowSelectionPrompt and SelectionPromptText I can easily have a "Select Customer" Line. I don't want to ask so much about my specific implementation, rather I am confused how to write unit tests for some scenarios.
For example my current tests cover the control being created properly during load and having its output render properly but I am lost as to how to test what happens when the control gets posted back. Can anyone give me some advice on how to test that? I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt?
"I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt."
By definition, you are not asking to "unit test"; you are looking for an "integration test". If you are not mocking the major dependencies, in this case, the ASP.NET runtime components, the what you are testing is the integration between your control and ASP.NET.
If you do not want to mock out the HttpContext and friends, then I would suggest an automated web testing framework such as Selenium or NUnitAsp.
Update: Based on the comment. Don't have the code access directly the IsPostback or other asp.net stuff. Wrap them with simple classes/interfaces. Once you have done that, send mocks that implement those interfaces. This way you don't have to mock the whole HttpContext, just the pieces that matter for the code (which are really clear based on the interfaces involved).
Also, given it is an asp.net custom control, you don't want to force requirements on external things like dependency injection. Have a default (no parameters) constructor, that sets up the control to use the asp.net stuff. Use a constructor with more parameters to send the mocked versions.
Initial answer:
It seems to me you are looking for a happy middle between unit tests and integration tests. You are working with a custom control, which can go wrong on different parts of the asp.net's page lifecycle.
I would:
Check if you can move parts of the code
out of the custom control to separate
classes, you can more easily unit test
For simple scenarios, rely on the functional tests of the rest of the project to catch any further issue with the control (use watin / selenium rc).
For more complex scenarios, as if the control will be used in different parallel projects or will be delivered to the public, set up some test pages and automate against it (again watin / selenium rc).
You write the tests in watin / selenium rc in c#, and run them in your "unit" test framework. Make sure to keep them separated from the unit tests, since they will clearly run slower.
Ps. I haven't used ms test support for asp.net, it might have some support for what you are looking for.

Resources