Is there an alternative for using a .testsettings file with TestCases and Microsoft Test Manager? - unit-testing

We have a peculiar situation here that is causing our automated tests to fail on a newly created lab environment, using TFS 2012.
We've always had a bunch of 'unit' tests that tested our DAL code, which in turn uses the Enterprise Library Data Application Block to perform operations on the database. This was setup quite a few years ago, to enable our clients to choose either SqlServer or Oracle databases alongside our product, taking advantage of the DatabaseFactory class and all the supporting generic interfaces and classes in the entlib.data. I mentioned 'unit' like this because these are actually not pure unit tests but integration ones, seeing as they require a real database to work.
To test the same SQL code against both databases, we maintain two separate .config files inside a 'Resources' folder in our TFS project branch, pointing to our test databases:
Resources\SqlServer\ConnectionStrings.config (SqlServer specific connection strings)
Resources\Oracle\ConnectionStrings.config (Oracle specific connection strings)
In the root Resources folder, there are two accompanying .testsettings files, responsible for deploying files specific to each database:
Resources\SqlServer.testsettings (which deploys the SqlServer\ConnectionStrings.config file)
Resources\Oracle.testsettings (which deploys the Oracle\ConnectionStrings.config file)
Since the whole structure is in source control, the testsettings is able to find the .config files by using relative paths, allowing us to test everything without having to setup parameters manually.
On devs machines, we always select the SqlServer.testsettings file when running the tests, so that they don't need to have the whole oracle environment installed to validate their changes before checking in the code. The Oracle side of the validation always occurred in our build process, where we actually test every method twice: first using the same SqlServer.testsettings used by the developers, and then using the Oracle.testsettings.
This way, we can setup our test assemblies' app.configs to redirect the connectionStrings node to an external file, like this:
<configuration>
<connectionStrings configSource="ConnectionStrings.config"/>
...
When the tests are run, mstest copies the adequate ConnectionStrings.config file to the test's working folder, based on which .testsettings was used to initiate the run.
This was working fine until today, when I discovered that tests started through Microsoft Test Manager ignore the Visual Studio .testsettings files. Now I'm trying to run these same tests in our lab environment but the ConnectionStrings.config files are not deployed (understandably) and the tests fail.
How can we achieve this without using .testsettings files? After having huge headaches trying to setup oracle correctly in our new x64 build server, we disabled Oracle tests in the build definition. Now that we started setting up our lab environment, we thought about having one of the machines in it configured with our whole system using Oracle, enabling us to again run these 'unit tests' with oracle-specific connection strings to validate our queries. At the same time, we want to keep testing everything locally and on the build server using SqlServer also.
I think using [DeploymentItem] in this case is impossible, since it is meant for static files and not selectable, dynamic ones like our current setup.
Is there any equivalent to the .testsettings deployment process that we could use with TestCases inside MTM/Lab Env? On the Properties tab for our TestPlan, I can see the Automated Runs -> Test Settings option, but that only seems to allow deployment by specifying absolute paths (which will actually be resolved on the target machines). Is there a way to specify a relative path there, pointing to our ConnectionStrings.config files checked in on TFS? Maybe yet another alternative exists that I'm missing, perhaps using multiple build configurations?

Create separate build configurations for each of the server types by going into Configuration Manager and click New under Active solution configurations. Edit the project file and do something like this:
<PropertyGroup Condition="'$(Configuration)' == 'Oracle'">
<appConfig>App.Oracle.Config</AppConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'SQL'">
<appConfig>App.SQL.Config</AppConfig>
</PropertyGroup>
Then ensure you have the correct connection strings in each of the config files. You can then configure TFS to build using those build configurations.
More info on using PropertyGroup and Condition, MSBuild Configurations and MSBuild project properties

Related

How do I create a TFS2017 Build Task equivalent to Visual Studio's Web Deploy Publish method?

I am trying to complete Continuous Integration/Continuous Deployment automation for a web application project. I have been helped by a series of SO posts link1, link2, link3 and things are now running, except the upload to the hosting server is longer than it needs to be; I currently upload all files instead of just the ones that changed.
When creating the TFS2017 Build (or Release) there are many Task options, including some from the marketplace. I'm referring to, in this case, the dialogue for a Build as shown below:
I'm currently using a PowerShell script which seems a little archaic and inefficient as noted above. Do any of the tasks available to us mimic the Visual Studio 2017 Web Deploy Publish Method which runs quite nicely and quickly? If not, what can I use for an 'intelligent' upload process that checks whether or not a file must be uploaded?
Unfortunately, there is no this kind of build task could mimic the Visual Studio 2017 Web Deploy Publish Method for now.
The method trough VS IDE will dynamically check if some files need to be uploaded or not.
However through TFS build task or powershell script will not do this, just simply copy all files you assigned. Afraid there is no workaround for an 'intelligent' upload process that checks whether or not a file must be uploaded. Since we don't how VS IDE did this.

Deploy multiple Content Delivery Servers with same confguration

I am building out a Sitecore farm with multiple Content Delivery servers. In the current process, I stand up the CD server and go through the manual steps of commenting out connection strings and enabling or disabling config files as detailed here per each virtual machine/CD server:
https://doc.sitecore.net/Sitecore%20Experience%20Platform/xDB%20configuration/Configure%20a%20content%20delivery%20server
But since I have multiple servers, is there any sort of global configuration file where I could dictate the settings I want (essentially a settings template for CD servers), or a tool where I could load my desired settings/template for which config files are enabled/disabled etc.? I have used the SIM tool for instance installation, but unsure if it offers the loading of a pre-determined "template" for a CD server.
It just seems in-efficient to have to stand up a server then config each one manually versus a more automated process (ex. akin to Sitecore Azure, but in this case I need to install the VMs on-prem).
There's nothing directly in Sitecore to achieve what you want. Depending on what tools you are using then there are some options to reach that goal though.
Visual Studio / Build Server
You can make use of SlowCheetah config transforms to configure non-web.config files such as ConnetionStrings and AppSettings. You will need a different build profiles for each environment you wish to create a build for and add the appropriate config transforms and overrides. SlowCheetah is available as a nuget package to add to your projects and also a Visual Studio plugin which provides additional tooling to help add the transforms.
Continuous Deployment
If you are using a continuous deployment tool like Octopus Deploy then you can substitute variables in files on a per environment and machine role basis (e.g. CM vs CD). You also have the ability to write custom PowerShell steps to modify/transform/delete files as required. Since this can also run on a machine role basis you can write a step to remove unnecessary connection strings (master, reporting, tracking.history) on CD environments as well as delete the other files specified in the Sitecore Configuration Guide.
Sitecore Config Overrides
Anything within the <sitecore> node in web.config can be modified and patch using Include File Patching Facilities built into Sitecore. If you have certain settings which need to be modified or deleted for a CD environment then you can create a CD-specific override, which I place in /website/App_Config/Include/z.ProjectName/WebCD and use a post-deployment PowrrShell script in Octopus deploy to delete this folder on CM environment. There are example of patches within the Include folder, such as SwitchToMaster.config. In theory you could write a patch file to remove all the config sections mentioned in the depoyment guide, but it would be easier to write a PowerShell step to delete these instead.
I tend to use all the above to aid in deploying to various environments for different server roles (CM vs CD).
Strongly recommend you take a look at Desired State Configuration which will do exactly what you're talking about. You need to set up the actual configuration at least once of course, but then it can be deployed to as many machines as you'd like. Changes to the config are automatically flowed to all machines built from the config, and any changes made directly to the machines (referred to as configuration drift) are automatically corrected. This can be combined with Azure, which now has capability to act as a "pull-server" through the Automation features.
There's a lot of reading to do to get up to speed with this feature-set but it will solve your problem.
This is not a Sitecore tool per se.

After importing the jacoco session into eclipse it shows zero coverage

I was following the following steps to measure the code coverage using jacoco:
I have instrumented my application wars files on the fly using jacoco agent.
Started the tomcat server.
Run some test cases.
Stopped tomcat server.
After stopping the tomcat server .exec coverage file gets generated in the destination folder.
In eclipse I opened my project work space.
I had imported the .exec file, but it shows 0% coverage for my maven multi-module project.
Please provide the steps how can I fetch exact coverage report from this .exec file.
Could it be that the classes deployed into Tom Cat were compiled differently, at a different time or with a different JDK from those in Eclipse?
The EclEmma import docs at http://www.eclemma.org/userdoc/importexport.html say
Warning: Imported execution data must be based on the exact same class files that are also used within the Eclipse IDE. If the external launch was based on different class files (e.g. created with different compiler) no coverage will be shown.
The execution data stores a hash of the class it was generated for, so if it doesn't match the hash corresponding class in Eclipse you'll see no coverage.
Make sure that the code base version is the same in both eclipse and what is deployed on the server.
JaCoCo creates Hashes of the files and if there are changes in the files, the hash gets screwed up and you will get a zero coverage.

TFS 2012 Auto-Deploy Process

I am trying to improve our general automation process. We use VS2012 and TFS2012.
Here is what I want to happen upon checkin to our CI branch:
BUILD
Build the selected projects / solutions as configured in the build definition settings.
Generate a deployment package that can be used to deploy the websites (without having to rebuild the entire project again)
Generate a nuget package that can later be published (without having to rebuild the entire project again, i need the dlls to match the symbols created from indexing so we can debug them)
TEST - IF AND ONLY IF BUILD WAS SUCCESSFUL
Run all configured unit tests.
DEPLOY - IF AND ONLY IF ALL UNIT TESTS PASS This is to prevent breaking changes entering our development environment
Take deployment package from (1.2) and publish it to it's intended environment (hopefully configured using Publishing Profiles and transforms)
PUBLISH - IF AND ONLY IF ALL UNIT TESTS PASS
Take nuget package from (1.3) and publish it to our private nuget gallery
I don't need a full tutorial (although that would be awesome) for the entire process, but more how to go about integrating it.
For instance:
Should I use msbuild on a wrapper project?
How do I deal with creating the packages upon build on the TFS build server?
How can I enforce the "IF AND ONLY IF ALL UNIT TESTS PASS" constraints?
What is the best / easiest way to perform the deployment /publishing after as part of the build.
This is the process we want to use and any help is realising this is very much appreciated.
And I'm sure many other people are interested in how to set about integrating this style of process.
Also if it's relevant most solutions have a mix of shared dll projects, websites / apis, and unit tests. One of the reasons I want this process is to be able to split them up and modularise our large dlls into smaller isolated units, which would be to unmanageable ATM without this auto publish mechanism.
Thanks,
Gary.
BUILD Build the selected projects / solutions as configured in the build definition settings. Generate a deployment package that can be
used to deploy the websites (without having to rebuild the entire
project again)
This is out of the box, add deployment profile to your projects, call them 'Release'
Add the following to your MSBuild Arguments
/p:DeployOnBuild=true;PublishProfile=Release
you don't have to use Release, as long as your Publish Profiles match what you put in the MSBuild arguments
This will generate the deployment files as part of your build (MSDEPLOY)
Generate a nuget package that can later be published (without having to rebuild the entire project again, i need the dlls to match the symbols created from indexing so we can debug them)
See Nugetter on code plex http://nugetter.codeplex.com/
TEST - IF AND ONLY IF BUILD WAS SUCCESSFUL Run all configured unit
tests.
Should be out of the box, but you can change the build template to fail the build should compilation be unsucessful, if this suits your needs better.
DEPLOY - IF AND ONLY IF ALL UNIT TESTS PASS This is to prevent
breaking changes entering our development environment Take deployment
package from (1.2) and publish it to it's intended environment
(hopefully configured using Publishing Profiles and transforms)
PUBLISH - IF AND ONLY IF ALL UNIT TESTS PASS Take nuget package from
(1.3) and publish it to our private nuget gallery
See Nugetter on codeplex as listed above

Deployment of files other than source code

I am starting to prepare a roadmap for our release process. We are at present using tortoise svn and ant for building source. I am considering implementing continuous integration and would like to know right direction for the choices below:
Firstly, the present process is such that a developer would work on a file, commits that file directly to repo. Others would run the tortoise update command to pull in the required changes. The same process is followed on the build server where in would update the source code, build and then deploy to qa and production servers. However, this process lacks control of repo since during an update, unwanted code is also pulled in case two developers worked on the same file fixing two different issues. One approved by qa and other rejected. How can i overcome this scenario.
Secondly, apart from source we have a bunch of other files such as xml files, css,js etc . How do i automate deployment of these files? I have configured cruisecontrol on my local machine and it works fine when it comes to executing a build but now sure how to handle other files since updating those files in production seems risky and error prone. Any suggestion in this would be really helpful.
You could try integrating PowerShell with CruiseControl, our team has CC fire off the build process and then PowerShell to copy the resulting project files (code and others) to production or a test site or wherever.
I'd suggest to deal with the lack of repository control that you create a candidate Branch off your Trunk and designate that as your Integration code. Once it's settled and necessary changes have been committed or pulled, promote it to Regression for further testing. Then once that testing is successful, promote it to Production.
In this process your developers wouldn't be committing to Production directly, but instead through an iterative process a new production repository will result, whose changes can then be reintegrated into Trunk so the process can start anew for the next release.