Data Driven Unit Testing - visual-studio-2010

Following code is used to inject data to the unit test from a CSV file.
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\CalculatePowerInputFraction05.csv", "CalculatePowerInputFraction05#csv", DataAccessMethod.Sequential), DeploymentItem("Simulation.Test\CalculatePowerInputFraction05.csv"), TestMethod]
public void CalculatePowerTest3()
{ }
I am setting the above properties by
Right Click on the test in test view -> Properties -> Connection String -> Choose CSV file
The problem I am facing is, |DataDirectory| contains absolute path. I am unable to run the tests in any other system. Is there any other way to provide input to TestContext so that problem with absolute path can be solved by giving relative path?

I have not worked on Visual Studio but in java I would do like this . Store the value of DataDirectory in some properties file and the read the value into your test. On different systems, the value of the properties file can be changed prior to running the test.

Related

NUnit 3 using Visual Studio 2015 How do I supply my tests with some parameters?

For example, I might write lots of Selenium tests for my staging website, now instead of writing the exact same code again but with the URL on my live website I'd like to reuse the code.
(I might need more than just the URL, I might need a different login/password etc.)
I thought it might be possible by using a .testsettings file and in my tests I could read what the current URL is that I should test against etc.
There has to be a way, how do you do it?
I would suggest storing your test configuration in a simple text based file. It could be as simple as URI on the first line, username on the second and password on the third, etc. Or, if you already have NewtonSoft.JSON in your project, create a simple JSON config file.
Then in your Test Assembly Setup, you could read in that file and parse it into a global static test settings object that you can access from all of your tests.
I would check the default TestSettings.json into source control so it is always available, then you can check if a TestSettings.local.json is present. If so, load it, otherwise load the default.
You could also set the defaults in code and override them if TestSettings.json is present.
To load the file before all of your tests run, use the SetupFixture attribute which allows you to run code when your test assembly loads, before all of your tests run.
namespace NUnit.Tests
{
using System;
using NUnit.Framework;
[SetUpFixture]
public class MySetUpClass
{
public static TestSettings Settings { get; set; }
[OneTimeSetUp]
RunBeforeAnyTests()
{
// Load your settings file here into the static
// Settings property
}
}
}

attaching unit test data to unit tests in visual studio

I heavily make use of unit tests for my developer needs (POCs, unit tests, etc). For one particular test method there was a line that went...
var file = #"D:\data\file.eml";
So I am referencing some file on my file system.
Now in a team when other people are trying to run my "personal" tests (POCs or whatever) they don't have a reference to that file in that path...hence the tests fails. How we'd have to normally make this work is to provide the test data, and allow the user to modify the test code so that it runs on his computer.
Any visual studio way to manage this particular problem?
Whats the benefit in this? Well, people can review the test data (email in my case) as well as the method I wrote for testing, and can raise defects in TFS (the source control system) relating to it if need be.
One way I often handle data files for unit test projects are to set the data files as Resources. (* Note that this link is for vs2010 but I have used this approach through vs2015RC).
In the project with the data file: Project -> Properties -> Resources and choose to add a resource file if you the project doesn't already have one. Select Files in the resource pane and click Add Resource or just drag and drop your data files onto the resource manager. By default resources are marked internal, so to access the resources from another project you have several ways:
In the assembly with the data files, add the following to your AssemblyInfo.cs file and this will allow only specified assemblies to access the internal resources
[assembly: InternalsVisibleTo("NameSpace.Of.Other.Assembly.To.Access.Resources")]
Create a simple provider class to abstract away the entire Resource mechanism, such as:
public static class DataProvider
{
public static string GetDataFile(int dataScenarioId)
{
return Properties.Resources.ResourceManager.GetString(
string.Format("resource_file_name_{0}", id));
}
}
Change the resource management to public (not an approach I have used)You can then access the data file (now a resource) from a unit test such as:
[TestCase(1)]
public void X_Does_Y(int id)
{
//Arrange
var dataAsAString = Assembly_With_DataFile.DataProvider.GetScenario(id);
//Act
var result = classUnderTest.X(dataAsAString);
//Assert
Assert.NotNull(result);
}
Note that using data files as resources, the ResourceManager handles the file I/O and returns strings of the file contents.
Update: The test method in the example above is from an NUnit project and is not meant to imply process, but a mechanism by which a data file can be accessed from another project.
What you'd normally do is add the file to your project and check it into TFS. Then make sure the item's settings are:
Build action: Content
Copy to output: If newer
Then put an attribute on your Test method or Test class:
[DeploymentItem("file.eml")]
You can optionally specify an output dircetory:
[DeploymentItem("file.eml", "Directory to place the item")]
If you put the files in subdirectories of your test project, then adjust the attribute accordingly:
[DeploymentItem(#"testdata\file.eml")]
The file will be copied to the working directory of your test project and that makes it easy to access from your test code. Either load the file directly, or pass the path to any method that needs it.
If you tests expect the files in a specific location you can use a simple System.IO.File.Copy() or System.IO.File.Move() to put the item in the place you need it to be.
The process is explained here on MSDN.
I suppose the most straight forward way is to simply add whatever to the project, and set the correct value for Copy To Output Directory. In other words, say your data is in a text file.
Add text file to your test project
Right-click to access properties window
Set copy to output directory field as Always or Copy if newer.
Now if you build the test project, the file gets copied to your output directly. This enables to write unit test code of the fashion:
var dataFile = File.OpenRead("data.txt");

How can I replace config file database links in one place in source code? (asp.net/razor)

I have an ASP.NET/Razor 3 web application which uses a SQL Server database via MS EntityFramework.
If/when I want to change the database connection string, for example to change the password or point to a different database (e.g. test vs. live), the string needs to replaced in about seven places in three different XML config files in the project (app.config, web.config, and app.release.config), which is an error-prone pain.
Worse, the default web server behavior on unhandled exceptions can include displaying sections of the config files to web users, which has in fact resulted in the web server displaying the lines that show the database path and password over the web. Not good.
For both reasons, and because this is not a product for which anyone would ever just edit the config file on the server (any change is pretty much, and may as well be, a build operation), I would much prefer to have the database connection information compiled into the web application and loaded from code rather than a config file, and to be able to do this such that when I want to change the database information, I can do it in one place instead of seven.
How would I achieve this?
The database connection string(s) can be set up centrally in 1 place, in the Global.asax.cs file, as part of the Application State, and then referenced from anywhere else in the project.
Step-1: Define the connection string(s) as static variables in Global.asax.cs:
namespace TestProject
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static string ConnectionString1;
public static string ConnectionString2;
protected void Application_Start()
{
#region Build application state for the app-specific items needed by us
ConnectionString1 = "Server=yourserver;Database=yourdb;etc etc";
ConnectionString2 = "Server=yourserver;Database=yourdb;etc etc";
#endregion
#region Code auto-generated and needed by system - do not change
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
#endregion
}
}
}
Step-2: Use the strings from anywhere else in the project:
string cnxStr1 = TestProject.MvcApplication.ConnectionString1;
string cnxStr2 = TestProject.MvcApplication.ConnectionString2;
(Please note that by default, the strings would be accessible only from within the same project. You will need to add references to the project if you need to use the strings from any other project within the same solution.)
The answer above by Krishna is pretty good. For me I would personally prefer to have them as static string in a static class and use it where ever is needed.
If you don't want to put the connection strings in the global file, you can:
Create a separate .config file for connection strings. e.g.
connectionStrings.config.
Create a hard-link to this file or the
folder containing this file that's in the same directory as your
other application.config and web.config files.
Set the configSource property on the connectionStrings element in each app.config or
web.config.
From then on, you only have one place to manage your connection strings that are common between apps.
The reason for the hard link is that configSource must reference a file in the same folder or sub-folder of the folder containing the application config.
Note that changing the connection strings will recycle all your web application pools that use them. For console, desktop, and service apps, you will have to restart for changes to take effect.
For the second problem you describe, you could have a separate connectionStrings.config file for each environment: development, test, production. Using config transforms or some other process, you only have to update the configSource property in each connectionString element to switch environments.

How to perform data driven load testing using LoadUI

I am load testing a web service.
Is it possible to perform data driven testing using loadui? If yes, how?
We can just give requests to web runner (where url is given) but I am not able to feed any data.
This article in the loadUI documentation explains how you do it. Basically, you have to use a soapUI DataSource via the soapUI Runner.
You can do this with SoapUI & LoadUI [with free versions :-) ]
In SoapUI create a TestSuite, then create TestCase. In TestCase define custom property... for example property with name "firstName"
Then in your request you can use values like this
${#TestCase#firstName}
Save a project and open LoadUI.
click on FLOW -> choose DataSource
Browse your input file. Right Click -> settings , modify separator for your needs.
check loop option to TRUE.
After that, you can use some Runner, right click on it -> Settings -> Properties
Now you can see all TestCase Properties (defined in SoapUI).
Now u need just to make transfer from datasource to SoapUIRunner
For column value you can use someting like this:
${#Data Source 1#firstName}\
Hope this helps.
Cheers
Nikola

Packaging Visual Studio LoadTest Solution

I have a VS 2010 Load test solution that contains quite a web tests and a bunch of Load tests. All of the web tests in this solution are data driven and use a SQL DB as the data source. Also, all of the data sources are set to random access method.
Now, whenever I change the data source or copy this solution to a different machine to test another deployment, I have to manually change the data source for all the web tests. The moment I change the data source, the access method gets reset to "sequential" which is the default setting. Now, I will have to change the access method also manually.
So, Is there a way I can package the VS Load Test solution so that the data source and access methods can be specified as parameters to the deployment package?
Note: Only the data source name changes but not the SQL DB schema for the data driven web tests.
The DataSourceAttribute can get all of it's properties from the configurations file of the application.
Here is a page that tells you how to use configuration files to place the connection string.
Walkthrough: Using a Configuration File to Define a Data Source
As you can see you may place the connection string in the app.config file, in the section <microsoft.visualstudio.qualitytools>:
<microsoft.visualstudio.testtools>
<dataSources>
<add name="MyJetDataSource" connectionString="MyJetConn" dataTableName="MyDataTable" dataAccessMethod="Sequential"/>
<add name="MyExcelDataSource" connectionString="MyExcelConn" dataTableName="Sheet1$" dataAccessMethod="Sequential"/>
</dataSources>
</microsoft.visualstudio.testtools>
In code usage of attribute:
[DataSource("MyJetDataSource")]
Reference:
The following links are just for reference:
How to: Create a Data-Driven Unit Test : creating data-sriven tests
Working with Load Tests : understanding load tests
DataSourceAttribute Class : docs for the attribute
DataSourceAttribute Constructor (String) : ctor that allows external connection string
DataSourceAttribute.DataSourceSettingName Property
Covert the web tests into coded web tests. In the code you will see the data binding code. Whenever you change the data source you can simply use find and replace all for data source name.
I don't think there is way to include this in deployment package.

Resources