Showing posts with label Continuous delivery. Show all posts
Showing posts with label Continuous delivery. Show all posts

Thursday, June 7, 2018

My new course : Continuous Delivery with Visual Studio Team Services published


Over the last 3 months I was busy working on my course on Continuous Delivery with Visual Studio Team Services. 

The course is published by Packt - a leading UK provider of Technology eBooks, Videos and Blogs, and their editors and marketing department has done a fantastic job of helping me with with creative graphics and animations to bring life to this course.


This course is intended for software development professionals who want to learn about Continuous Delivery in a technical value stream as supported by Visual Studio Team Services in order to continually deliver working software at scale. You'll learn how to create, build, test and release a containerized ASP.NET web api to kubernetes cluster on Azure.


The course consists out of seven sections:
  • Introduction to continuous delivery - We'll learn about Continuous Delivery, the business goals and principles of Continuous Delivery
  • Introduction to visual studio team services - We'll learn about the different elements of Visual Studio Team Services and how they function and how using these connected tools you can move your organization to a full-fledged continuous delivery implementation.
  • Setting up the development environment for .net core applications using Docker:
  • Source code management in VSTS : We'll have a look into the Git version control in VSTS and discuss branching strategies like trunk based development and how these concepts relate to continuous delivery.
  • Build management in VSTS : We'll see how to setup a Continuous integration build in VSTS that helps the code stay robust enough that team members can fearlessly make changes to the code base without worrying about breaking existing functionality.
  • Continuous testing : This section we’ll learn how to ensure that an application's components function correctly when assembled together. We'll see how to automate the tests and include them in your Continuous Integration scheme to get the most value from the tests.
  • Release management in VSTS : This section shows you how to do automatic deployments by using Release Management. You'll learn Release Management in VSTS, how it works and how to use release management to deploy our sample application to a Kubernetes cluster on Azure.

The course follows a phased approach to continuous delivery to automate build, deploy and management of .net core applications to Azure Container Services using VSTS ALM. By the end of this course, you'll have the necessary knowledge to create a fully automated build and release pipeline using Visual Studio Team Services for your .NET applications. And don't forget to check the course at https://www.packtpub.com/virtualization-and-cloud/continuous-delivery-visual-studio-team-services-video

Saturday, August 5, 2017

Don't ignore the 'Core' in Continuous Delivery

You see, I'm a person who loves to write code, travel around the world, take nice pictures and eat!!! But nothing less than that, I also enjoy running (especially in the morning!!!, ). It's amazing to have that feeling of the fresh air, smell of the grass and sense the muscles working while observing the surroundings. My running helps me to do my job better because it helps clear my mind, relieves stress and builds a lot of confidence. Its provides me with those moments with great ideas and solutions to most of the problems you have at work or life. By the time you finish running, you have already set up the goal for the day with a certain amount of clarity about the activities that you have to do.

The more I started running, the more I loved challenging myself with those extra miles and pace. But with my overgrowing excitement, I was making the obvious mistake.. I was running too much, too soon, too fast. While doing so, I forgot about the "little things" that help stay healthy and flexible. I started getting injuries, my hips and hamstrings were always tight. I was breaking down with back pain and injuries. I knew I was doing something wrong and it was time to get an expert advice. Having heard the back pain story many times, the physio explained me about the importance of 'Core' muscles and the exercises to do that would strengthen my muscles and improve my core stability. He suggested doing squats, swimming, pull ups, crunches etc. So I decided to give my running a break and focus on core building. It felt a bit off in the gym doing all those non equipment exercises while everyone else was lifting those 20/30 kg dumbbells, but a month after training, I started noticing the difference. I felt more stronger with increased muscle mass, my posture was better, lost some body fat and I was more agile!!! I started running again and this time I noticed the difference immediately. My core helped me to maintain an efficient running form  helping with better stability, balance, posture and overall control.

In short, lesson learnt from my running experience. "Ignoring core strength in your training program may look like working for a short term, but is a recipe for long-term disaster. Lack of core-strength and flexibility causes your body to find a path of resistance towards running or cause the body to adapt in a negative fashion that will most likely lead to complex injuries!!!"

Well how does this relate to continuous delivery and DevOps? The answer is , before immediately adopting a CD tool and start working on the pipeline, you should prepare the teams and the organization with the core of continuous delivery. The core practices like version control, build automation, test automation and continuous integration increases software process agility and helps create an organizational culture and structure to fully embrace CD.

In this post, I’ll describe some of the core practices of continuous delivery  that helps delivering software feature more frequently and reliably. 

Version control everything

Putting everything in version control (source code, build scripts, test scripts and data setup, monitoring scripts etc.) This helps in keeping track and control everything. Keeping track of the changes gives the flexibility of undo or replay any changes easily in all environments including production. You can also understand who made a change and why. Version controlling also creates the first level of built-in safety net, preventing any out of process, locally made changes or manual overrides from entering the production environment. Every change a developer makes must in the source control, any failure to do so will be overridden in the next deployment if not present in the source control.

Practice TDD

TDD is a software development approach where the development of code is driven by first writing an automated test case, followed by writing the code to fulfill the test and then refactoring. With continuous delivery, it’s very important to have the tests pushed into source control along with the implementation code. This helps in ensuring that every new code pushed will be tested in the same build process. This eliminates the risk of delivering to production the code that does not meet quality requirements.

These automated tests helps identify errors in a really short period of time. These tests give developers very fast feedback when something breaks. These tests are also called change detectors. When you make a change, the tests will detect very soon if there are any problems or mistakes. With continuous delivery organizations need the have the ability to make frequent releases of their software without the risk of breaking existing features or adding new bugs. The success of the business depends on how fast it can react to changing environments and address the new improvement suggestions with assurance. Test-driven development is the methodology that makes such flexibility, maintainability, and extensibility possible.

Continuous integration

"Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly." - Martin Fowler

Continuous integration process runs ensures that the tests are executed every time a change is pushed into source control and ensures that the new changes didn’t break any other parts of the software. Every push automatically triggers multiple tests. Then if one fails it’s much easier to identify where the error is and start working to fix it.

Automate everything

Automation is the heart of every successful continuous delivery transformation process and the single biggest enabler for CD. The success of continuous delivery lies in stable environments, consistent build and test process and happy releases. Automation can be used to make the release process more deterministic and to bridge the gap between development and production. Development teams can learn from operations the value of automation and how to create automation scripts to improve the overall process. Together the team is responsible for defining the desired state of the infrastructure and convert this to code. The degree to which your organization can achieve successful one click deployment process that can be initiated by anyone whenever needed depends on the level of automation at every stage. At the processes like code analysis, testing, environment provisioning, defect detection and prevention at all stages should be automated. Any manual tasks should be treated as technical debt and later picked up as part of the sprint and addressed.

Test automation

The key to building quality into our software is making sure we can get fast feedback on the impact of changes. Test automation can automate some repetitive but necessary tasks in a formalized testing process already in place, or perform additional testing that would be difficult to do manually. Companies adopting continuous delivery should ensure that when issues are identified they can be managed and resolved quickly and definitively. The easiest and effective way to achieve this is by having an automated test suite incorporated in the release pipeline and CI process. This kind of a process where automated regression, performance and security tests are constantly executed as part of the deployment strategy helps identify issues early and deal with them before they reach the later stages of the deployment cycle/pipeline.

Monitor and measure everything

Proper and effective monitoring of the entire process and environments is important to provide crucial information that ensure service uptime and optimal performance. It's important to measure the progress of the approach to know whether teams are improving or making progress. With the support of proper data and metrics, it’s easy for teams to inspect the current way of working and come up with ideas or processes to improve the overall CD/ DevOps movement. Measuring the current capabilities and process helps teams determine the problem areas and defined focus points for making a change.

An important DevOps practice is to work with application monitoring and insights to enable full end-to-end traceability in a product to provide both operational insights and  usage understanding

Keep focus on these core practices and move forward with your continuous delivery journey!!!
“….to satisfy the customer through early and continuous delivery of valuable software” - #1 of the twelve principles behind the agile manifesto.

Sunday, July 16, 2017

Why automated end to end tests may not solve your quality issues

Our customer asked us to help us with an approach for end to end testing. The problem the teams were facing was mainly due to the errors detected during the integration phase/ environment where end to end tests were executed. During the discussions with the teams we noticed that the organizing of teams was based on loosely coupled software components. The teams worked on individual components that were versioned, tested and deployed independently. They had development or test environments were the system tests were executed as part of the build or release process. These system tests were executed against the stubs of the dependent components and verified successfully.

The teams used to get requirements per component which did not specify the entire use case, most of them were in the format of “if a message in format XYZ is given to the component, then do something and send the output to another component in the system in a different format.” Each team developed these user stories and delivered the stories with tests to ensure that the components worked fine, given the correct data is provided in the expected format.

But there was no guarantee that the whole system was working as expected. Most of the time, there were integration issues, due of the wrong versions of components in an integration environments or schema mismatches etc. Different component teams worked in isolation and failed to communicate about the recent releases to other teams. This introduced the need of a separate team to test the system as a whole. The responsibility of this team was to create end to end tests to check and ensure whether the whole system worked properly with multiple components deployed.


The end to end tests now helps in identifying  integration issues before deploying to an higher environment. Only the problem was not completely solved!!!

The issues detected by the integration test team was reported back to the component teams and which was normally not picked up in the current sprint, but has to be put into the backlog for later iterations. This introduced waiting periods and tensions between the different silo teams. Developers were working on parts of the complete applications who were not aware of how the complete system functions were not able to test the system as a whole.

End to end testing was not a solution to this situation, but just a workaround to suppress the problem from getting into higher environments. A better solution will be to organize the teams into feature teams where the team can shift their focus on value delivery and work on business features rather than technical components. Now the teams have acceptance criteria that maps a customer centric use case, rather focusing on a part of the use case. Compared to the component teams, feature teams can provide better design decisions and thus better tests because of the knowledge of the whole application,  technology stack and use cases. The automated tests delivered as part of the user stories now cover the whole feature and not only part of the application.


The feature team as a whole now have the required skills to implement the entire customer centric feature. The integration test team members are also part of the feature teams and assist in ensuring the correct functional tests are captured as part of the development process.

Thursday, August 4, 2016

Application deployments, best practices


With more and more teams getting ready with practices like continuous deployment and DevOps, there are lot of questions about the best practices regarding application deployment. I've been working with projects and setting up continuous delivery and automated deployments as part of the work. Below are some of the practices that I follow for application deployments.
Automate
There is a lot of focus on automation nowadays and a lot of tools and information is available to automate the manual actions in the deployment process. Almost every deployment automation tools allows complete customization and extensibility to make use of scripting languages that are used to carry out OS specific tasks. This makes it very easy to use these tools in the process even though you have a specific task to perform that is not available out-of-the-box in the tool that you are using. For .NET applications you can use PowerShell for example to do almost anything on windows environments.
Build once, deploy it many times
For avoiding situations like, "it works in the Test environment but not in Production". you need to use the same binaries that were installed and tested on lower environments when deploying to higher environments. For automated deployments to go risk free, we need to have the confidence that we are deploying the same package that was tested and approved from a lower environment. If you are planning to recompile the code base every time a deployment is happening, there are lot of hidden changes and troubles coming along with that process, which makes the deployments unstable.
Maintain a repository for the build artifacts
Things can sometimes go wrong and sometimes its needed to roll-back to a known-working version. Having an artifact repository for your packages not only will help you in using the same version on every environment, but also to locate old versions of an application without having to build them again. Also its a stable version that was working before!!!
Change configuration variables at deployment time not at build time
One of the common challenges with applications which migrate through the usual lifecycle of environments such as development, test and production is getting the configuration context right. Some of the most common examples are connection strings, trace modes etc. There are multiple ways to handle this problem with one of them being making use of configuration file transformations as part of the build process. This can introduce the same risk as rebuilding binaries for each environment. It’s a good practice to make use of the deployment tool to apply environment specific configuration changes during deployment time to the applications. This will allow you to be flexible with the latest changes in the environments.
Don’t customize the deployment process or steps based on environments
It’s always good to treat your deployment process the same across environments. This helps you to create more reliable and predictable deployments across environments. A lot can go wrong when you try to make adjustments in the deployment process based on environments. Let’s keep it simple J

Wednesday, June 8, 2016

DevOps and the continuous flow of value

If it was the introduction of Agile that the software industry was heavily benefited by involving the customer early in the process, it’s the introduction of DevOps that brings Agile to its full potential by enabling the change in the organization to make sure that the focus is on continuous value delivery.



DevOps more than tooling is a cultural change in the workplace that brings people closer with emphasis on collaboration and communication to work on a shared vision for continuous value delivery. DevOps professionals ensure reliability and speed in this process by depending heavily on automation of infrastructure, software development, testing and feedback process. This requires all the members in the team (Operations, Developers and Business) to work hand-in-hand to improve the organization’s competitiveness, thus creating a highly visible change that benefits the internal process as well as the end users.

The continuous flow of value means that teams are capable of moving an idea into production quickly and frequently without compromising on quality. DevOps teams achieve this by removing silos and have multidisciplinary skillsets in the team needed to make this possible. With the help of automated deployment pipelines, automated acceptance testing, automated infrastructure etc. new features can reach production within a very short span of time. To improve the effectiveness  of the DevOps transition and increase customer happiness, teams should focus more on gathering real time application and user data. Services like Visual studio application insights provides easy configurable live monitoring on the application. It also helps detect and diagnose performance issues and understand what users actually do with the application. DevOps teams make use of these kind of tools to continuously improve the usability and performance of the products they are creating.

Another simple way of testing the acceptance or likability of the new feature is by adding a quick and easy feedback mechanism in the product itself. You can make use of ideas like implementing a like button or a simple smiley to collect user feedback on the live feature. These kind of actionable evidences play a major role in ensuring that the actual value is reaching the customers faster and thus creating a success story for your DevOps journey.

Sunday, April 17, 2016

The 4 pillars of DevOps


Evolved from the concept of continuous improvement of the software delivery process, DevOps is a movement focused on improving communication, collaboration and integration between the software development and IT operation teams. DevOps emphasizes on bridging the gap between these teams by focusing on delivering software faster, and creating a success metric based on how often they can release rather than on KPIs or metrics that are in conflict of each other’s interest or areas of work.

The DevOps movement is built around a group of people who believe that the application of a combination of appropriate technology and attitude can revolutionize the world of software development and delivery, where the goal is to improve the flow from development to operations by working together and understanding each other’s challenges. These goals are achieved by creating a set of practices and patterns around 4 main pillars namely:

Communication

To create better software and do better releases, the team needs to constantly communicate with each other from the planning to release phase to solve impediments and improve the quality of the release process. The team needs to be physically together and need talk to each other and continuously learn from each other during the process. The communication process is often facilitated with the support of tooling like Slack, Trello etc.

Collaboration

Collaboration is key for a true DevOps approach. Better collaboration between the dev and ops teams help them achieve a streamlined process which helps the team in
  • Better understanding of the target infrastructure and be well prepared with the changes in the product required for the changes in the infrastructure
  • Prepare the target infrastructure with the changes needed for the upcoming releases of the software to avoid delays in the releases due to challenges in the environments.

Successful DevOps teams work effectively with collaboration platforms like Yammer, SharePoint etc. to facilitate this process.

Automation

Automation is the heart of every successful DevOps transformation process and the single biggest enabler for DevOps. The success of DevOps lies in stable environments, consistent build and test process and happy releases. Automation can be used to make the release process more deterministic and to bridge the gap between development and production. Development teams can learn from operations the value of automation and how to create automation scripts to improve the overall process. Together the team is responsible for defining the desired state of the infrastructure and convert this to code.

Tools like PowerShell DSC, Chef, Puppet etc. can  be used to automate almost anything and everything that the team needs. During the process, the operations learn about version control, testing, CI builds etc. when working together with the development teams.

Monitoring

Monitoring in DevOps teams are required to provide crucial information that ensure service uptime and optimal performance. It's important to measure the progress of the approach to know whether teams are improving or making progress. With the support of proper data and metrics, it’s easy for teams to inspect the current way of working and come up with ideas or processes to improve the overall CD/ DevOps movement. Measuring the current capabilities and process helps teams determine the problem areas and defined focus points for making a change.


An important DevOps practice is to work with application monitoring and insights to enable full end-to-end traceability in a product to provide both operational insights and  usage understanding. Tools and technologies like ELK stack, Application insights etc. can be used for effective monitoring.

Monday, March 21, 2016

Metrics to keep you on track for a continuous delivery journey


Practices like continuous delivery helps software development teams produce software in short cycles. High quality teams achieve this by continuously integrating the software, building executables, and running automated tests on those executables to detect problems. By following this, teams are aiming to reduce the cost, time, and risk of releasing new versions of software into production. In most of the cases, organizations will make changes to their current processes or tools by following the general guidelines or recommendations as part of a CD/ DevOps adoption cycle. But it’s also important to measure the progress of the approach to know whether you are improving or making progress.
With the support of proper data and metrics, it’s easy for teams to inspect the current way of working and come up with ideas or processes to improve the overall CD/ DevOps movement. Measuring the current capabilities and process helps teams determine the problem areas and defined focus points for making a change.

What are the metrics for continuous delivery?

Well, it depends. There is no standard definition of metrics for continuous delivery. Below are some of the key metrics I've identified and used for measuring our progress and success of our continuous delivery adoption at work. I've seen that these metrics used in combination provides with enough details about our way of working as a software delivery team.

Committed to Done (PBI)

The time taken for the user stories per sprint to be in the done state from the committed state. The scrum team puts a story in the committed state when they have completed the discussion of the PBI/ user story in the sprint planning, created the tasks and agreed to build the story in the sprint. Done is when all the tasks and acceptance criteria’s are met. The product owner has agreed the PBI meets the specifications and quality standards. Teams should try to minimize the number of days it takes them to move the story from committed to done. This indicates whether the team’s reliability and whether the stories are sized properly.

New to Done (Task)

The time taken for the tasks to move from new to done state. Tasks should be ideally estimated to complete within 4-16 hours. Teams should focus on completing a task first and then move to the next one. New to Done metrics shows how the team is working on the tasks. Whether there are too many open tasks that all of them are closed at the last day of the sprint? Are the tasks too big? etc.

Team predictability/ reliability

Measuring how reliable the teams predictions helps business to create a stable product plan. Making the predictability metric available to the teams helps them plan, coordinate, and deliver predictably enough to make a release level commitment. A good way of calculating this is by using the data from sprints based on the number of points committed vs. number of points delivered per sprint. This metric helps teams become predicable in their estimating and sprint planning. It encourages smaller stories and more effort getting work ready prior to the sprint. Teams that use good engineering practices such as test-driven development, continuous integration, automated testing and deployment etc. are more reliable in their predictions and often have very less errors in the estimation

Velocity

Velocity is a metric that predicts how much work an agile software development team can successfully complete within a sprint. Velocity is calculated by counting the number of units of work completed in a sprint. Velocity is a useful planning tool for estimating how fast work can be completed and how long it will take to complete a project. Once established, compared with the team predictability metric, velocity can be used to plan projects and create reliable release forecasts, product completion dates, de-scoping functionality, resource planning etc.

Regression test duration

Regression tests helps teams verify that software that was previously developed and tested still performs correctly after it was changed or interfaced with other software. The purpose of regression testing is to ensure that changes such as those mentioned above have not introduced new faults. One of the main reasons for regression testing is to determine whether a change in one part of the software affects other parts of the software. Tracking the time it takes to complete a full regression test helps teams to device effective measures to reduce this time, hence helping them make new software releases faster. This means focusing on adding more automated tests than manual tests, creating parallel testing strategies, following good testing practices from the test pyramid etc.

Number of open bugs per sprint

Teams adopt practices like continuous delivery to create faster delivery of quality software to the end users. With shorter releases and automated releases, teams should maintain high quality standards to ensure that bugs are not shipped the customers. It’s important for teams to maintain a very low error ration in the software shipped to customers to ensure that customer satisfaction is high with the releases.

Team and P.O happiness

This is an index measuring the level of happiness in the scrum team per sprints. The trend of happiness says quite a lot about a group and how well everything is going regarding its goals, A happy team and members are productive and are working towards their mutual goal to deliver the product.

Percentage of failed deployments

The goal is to make sure that regardless of how often you deploy, what gets deployed doesn't cause a failure.  Measuring and keeping track of deployments allow teams to make adjustments in their process to achieve small-batch developments to update every few days, or even several times per day.

Check-in frequency vs. broken build time

This is the plot displaying the time taken to fix the broken builds within a  given time period. Continuous integration encourages practices like the whole team drops their work and verifies who should handle the broken build when notified. Check-in code to an already broken build creates a lot of complexity and waste. Teams should focus on integrating code changes frequently, so that integration doesn’t become such a hard process with ensuring that the build is stable.

Code coverage vs. Maintainability index

The metric shows the trend lines for code coverage and maintainability index of the code. With rising lines of code, it’s important for the teams to improve the quality of the code to make it easier for building new features in the product. Practices like improving testability helps you maintain a maintainable code base. These metrics can be easily generated by tools like SonarQube. The trend line displays how creating testable code improves the code maintainability. Also it’s a good indicator of deciding what your code coverage should be (at what point it stops adding value).

Mean time to recover

This measures how long it takes from when an incident is reported to when it is resolved. In general, this number needs to be trending downwards. This indicates both the responsiveness of your team as well as the capability to resolve and deploy solutions. Continuous Delivery automation with a combination of monitoring techniques and tools like Application insights/ ELK stack makes rolling out rapid fixes easier and spot failures quickly through a ‘production immune system’. Based on these practices the ideal DevOps team can produce frequent, rapid deployments with a low (and declining) failure rate and a short (and shrinking) recovery time

Cycle time

According to Dave Farley "Your cycle-time is the time it takes you to release the smallest possible change to your code following your normal release validations and procedures. Your cycle time should be short enough so that when an emergency hits, you can still release your fixes having validated them fully.". Teams should focus on reducing their cycle time by improving their software delivery practices. A reduced cycle time allow them to work in small batches, ensuring that each change is small-enough so that when it does go wrong it is simple to see where the problem lies and how to fix it.

Conclusion

As you can see there are a lot of metrics that you can choose from. Before adopting these in your team, it’s important to find out which of these metrics are important for your team and how they are applicable in your process. The idea is to have the right set of metrics and data that allows you to stay focused on the continuous delivery goal and put it to good use

Sunday, March 6, 2016

Microservices – Why does it matter for continuous delivery


Software delivery organizations across the globe has adopted continuous delivery as a central practice to build high quality software faster, with less stress and effort. One of the goals of continuous delivery is to make deployments as boring as possible. To assure that we need to deploy often and find errors as soon as possible before delivering the software to end user, continuous delivery promotes certain architectural approaches of a platform. Releasing often, with small changes, is extremely difficult task to perform for a complex application with a huge monolithic architecture. The idea of rearranging the software architecture into smaller, focused, domain-specific applications composed of microservices has gained a lot of popularity in the last 2-3 years.
Microservices are a new software development pattern emerging from recent trends in technology and practice. A microservice is an independent, self-contained process that provides a single business capability. Different Microservices act in concert as one larger system by communicating to each other using a language agnostic API. In microservice architecture each service is highly decoupled from each other and are created in mind to focus on one problem domain.


Monolithic and the problem for continuous delivery

Traditional monolithic applications are built as a single unit, where all the functionality is pulled into a single process and is replicated across multiple servers. The single application is responsible for all functionality including handling requests, authentication, executing business/ domain logic, persistence, logging, exception handling etc. Due to this behavior its makes it hard to add a small change in the system that involves building, testing and deploying the entire application. Scalability and availability involves running multiple instances of this application behind a load balancer on multiple servers even though the bottleneck lays in a single component in the application. As a result, updating monolithic applications become time-consuming activity that needs to have a lot of coordination between people involved in multiple functions and departments.
Apart from the issues related to deployment and scalability, there are some other challenges that this kind of architecture brings when the application grows in size.
A large code base makes it hard for all the developers to understand and modify the application. This makes the code base harder to manage and difficult to add new features which also results in bad quality creeping in as time progress. The team is forced to stick on the technology stack which was chosen at the time of starting the development and commit to the stack for a long-term. This also introduces dividing engineering teams at an organization level to focus on specific functional areas, like UI team , database teams etc. The coordination, development and deployment processes becomes harder with this structure which takes the teams a step backward in their journey towards practices like DevOps, continuous delivery etc.

How microservices helps?

In contrast to Monolithic applications, microservices makes independent management of business functionality by separating the functionality into smaller services that can be independently deployed, tested and scaled. With microservices scaling and deploying each service can be done independently without affecting the other parts of the system, by creating instances of these services across containers or virtual machines. In short a Microservice can be summarized as
“Applications composed of small, independently versioned, and scalable customer-focused services that provides a unique business capability and communicate with each other over standard protocols with well-defined interfaces.”
In the microservice approach the application is divided into smaller parts that communicate with each other with lightweight mechanisms like REST, message brokers etc.
Due to the highly evolving business needs, software applications needs to be build considering high scalability and availability to respond to the needs of customers in an agile way. This is only possible if, making change to a service is less expensive and risky. Microservices make this possible due to the fact that each service is operationally encapsulated by other services and are independently deployable without affecting the other services in the infrastructure. This makes easier for development teams to apply the changes and test them independently faster than ever.

Free white paper


The white paper addresses the common characteristics and challenges with solutions to your journey towards refactoring a monolithic to a microservice. You can download the complete article from this link.

Saturday, July 4, 2015

DevOps and PowerShell – Test automation with TFS API

Using the combination of TFS API’s and PowerShell, you can easily manage your TFS test cases, either as part of a build process or from a tool that supports invoking PowerShell cmdlets or scripts. In this post, I’ll show how to make use of the [Microsoft.TeamFoundation.TestManagement.Client] API’s to manage test runs in TFS or Microsoft Test Manager. The test management client API’s are internally used by MS visual studio Ultimate/ Test Professional editions to manage TFS test plans, and cases.
At the end we’ll create a PowerShell module with the functions that are needed for managing the test runs in TFS and use the functions to meet our requirements. The rest of the post contains sections defining the functions that are exposed as part of the Module.

Assemblies involved in the example:

The first step is to load the assemblies which are needed for our functions to interact with the TFS API’s

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client") 
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.TestManagement.Client") 
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client") 

The Microsoft.TeamFoundation.Build.Client assembly is used to get the details of the latest build that will be used to create a test run.

Get-TeamProjectCollection

In TFS a team project collection is used to group multiple team projects that needs a common set of resources or have a similar set of requirements or objectives.  A team project collection can be retrieved by using the GetTeamProjectCollection method on the TfsTeamProjectCollectionFactory class.

Function Get-TeamProjectCollection
{
      [CmdletBinding()]
      param
      (
            [Parameter()]
            [ValidateNotNull()]
            [Uri]$Uri
      )

      if(-not($Uri))
      {
            $Uri = "http://yourtfsserver:8080/tfs/defaultcollection"
      }

      [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($Uri)     

}

PS C:\> Get-TeamProjectCollection


Name                                    : tfsprajeesh\DefaultCollection
DisplayName                             : tfsprajeesh
CatalogNode                             : CatalogNode instance 59865478
                                            ChangeTypeValue: 0
                                            IsDefault: False
                                            MatchedQuery: False
                                            NodeDependencies: [0]
                                            NodeDependenciesIncluded: False

Get-TeamProject

A team project is a collection of work items, code, tests, work products, metrics, and so forth that is used by a defined team to track a common set of related work. The logical concept of a team project helps you determine what to include or exclude from the development of a software application.
In our sample, we will make use of the TestManagement API (you can also use the TeamFoundation.Client API to get the team project) to get the TeamProject object.

Function Get-TeamProject
{
      [CmdletBinding()]
      param
      (
            [Parameter(ValueFromPipeline=$true, Position=1)]
            [ValidateNotNull()]
            [Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]$TeamProjectCollection,

            [Parameter(Mandatory=$true, Position=0)]
            [ValidateNotNullOrEmpty()]
            [String]$Name
      )

    $service = $TeamProjectCollection.GetService([Microsoft.TeamFoundation.TestManagement.Client.TestManagementService])
    $service.GetTeamProject($Name)   

}

PS C:\> Get-TeamProjectCollection | Get-TeamProject -Name "TeamProject1"


TestEnvironments             : Microsoft.TeamFoundation.TestManagement.Client.TestEnvironmentHelper
IsValid                      : True
DefaultPageSize              : 200
DefaultPageSizeForTestPoints : 400

Get-TestPlan

A test plan lets you specify what you want to test and how to run those tests. You can create Test plans in Microsoft Test Manager or using the TFS API's. For more details on Test plans and how to create them follow the doumentation at https://msdn.microsoft.com/en-us/library/vstudio/dd286583(v=vs.110).aspx . To get a test plan instance based on the test plan name or test plan id, we'll make use of the TestPlans collection in the TeamProject object as given below.
Function Get-TestPlan
{
      [CmdletBinding()]
      param
(
            [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
            [ValidateNotNull()]
        $TeamProject,

            [Parameter(Position=1)]
            $Id,

        [Parameter(Position=2)]
        $Name
      )

    if($Id)
    {
        $TeamProject.TestPlans.Find($Id)
    }
    else
    {
        $TeamProject.TestPlans.Query("SELECT * FROM TestPlan WHERE PlanName='$Name'")
    }
}

PS C:\> Get-TeamProjectCollection | Get-TeamProject -Name "TeamProject1" | Get-TestPlan -Name "TestPlan1"


ObjectType                 : TestPlan
Name                       : TestPlan1
Description                :

Get-TestSuite

By using Microsoft Test Manager, you can organize test cases into a hierarchy of test suites inside test plans. For more information on test suites, follow the documentation at https://msdn.microsoft.com/en-us/library/vstudio/dd286738(v=vs.110).aspx. We can make use of the TestSuites collection of the TeamProject object to query a test suite based on the Id.
Function Get-TestSuite
{
      [CmdletBinding()]
      param
      (
            [Parameter(Mandatory=$true, Position=0, ParameterSetName="TeamProject")]
            [ValidateNotNull()]
        $TeamProject,

            [Parameter(Mandatory=$true,  ParameterSetName="TeamProject")]
            [Parameter(Mandatory=$false,  ParameterSetName="TestPlan")]
            [ValidateNotNull()]
            $Id,

            [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="TestPlan")]
            [ValidateNotNull()]
            [Microsoft.TeamFoundation.TestManagement.Client.ITestPlan]$TestPlan
    )

    switch($PsCmdlet.ParameterSetName)
    {
        "TeamProject"
        {
            $TeamProject.TestSuites.Find($Id)
            break;
        }
        "TestPlan"
        {
            $TestPlan.Project.TestSuites.Find($Id)
            break;
        }
    }   
}

PS C:\> Get-TeamProjectCollection | Get-TeamProject -Name "TeamProject1" | Get-TestPlan -Name "TestPlan1" | Get-TestSuite -Id  2


TestSuiteType          : StaticTestSuite
ObjectType             : TestSuite
Plan                   : TestPlan instance 23

Get-TestEnvironment

A lab environment is a group of computers that you manage as a single entity. Usually you use them for system testing. If you’re testing a distributed application such as a web app, you can perform realistic tests by deploying each component on a separate machine.
Lab environments let you collect diagnostic data from all the machines in the lab while you’re performing your tests. The data, such as event logs or Intellitrace files, are attached to the test results and to any bug that you create. For more details on Lab environments refer to the documentation https://msdn.microsoft.com/en-us/library/ee943321.aspx. The TeamProject has a collection of TestEnvironments which we can Query the Environment by name or id
Function Get-TestEnvironment
{
      [CmdletBinding()]
      param (
            [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
            [ValidateNotNull()]
        $TeamProject,

            [Parameter(Position=1)]
            $Name
    )

      $TeamProject.TestEnvironments.Query() | ? { $_.Name.EndsWith($Name) }
}

PS C:\> Get-TeamProjectCollection | Get-TeamProject -Name "TeamProject1" | Get-TestEnvironment -Name "Env1"


Id                      : bgvf6fb7-96f3-483c-4356-078148cf45de
Name                    : TeamProject1.0.Env1
Description             :


Get-TestConfiguration

Test configurations will help users to test applications with different configurations like web browsers, different operating systems etc. A detailed description about test configurations is provided here https://msdn.microsoft.com/en-us/library/vstudio/dd286643(v=vs.110).aspx. The TestConfigurations collection property in the TeamProject can be used to find and use a specific configuration during a test run.

Function Get-TestConfiguration
{
      [CmdletBinding()]
      param
    (
            [Parameter(Mandatory=$true, ValueFromPipeline = $true)]
            [ValidateNotNull()]
        $TeamProject,
     
            [Parameter(Mandatory=$false,  ParameterSetName="Id", Position = 1)]
            [int]$Id,
     
            [Parameter(Mandatory=$false,  ParameterSetName="Name", Position = 1)]
            [string]$Name
    )

    switch($PsCmdlet.ParameterSetName)
    {
        "Id"
        {
            $TeamProject.TestConfigurations.Find($Id)
            break;
        }
        "Name"
        {
            $TeamProject.TestConfigurations.Query("SELECT * FROM TestConfiguration WHERE Name='$Name'")
            break;
        }
    }
}

PS C:\> Get-TeamProjectCollection | Get-TeamProject -Name "TeamProject1" | Get-TestConfiguration -Name "Internet Explorer Browser"


ObjectType        : TestConfiguration
Name              : Internet Explorer Browser
Description       : Use this configuration to run an automation test in internet explorer
AreaPath          : TeamProject1
IsDefault         : False

Get-TfsBuild

During a test run, it’s important to specify the TFS build to be used that contains the test methods that the tests are executed against. A team build can be queried using the Microsoft.TeamFoundation.Build.Client API, by providing the TeamProject and Build definition name.
Function Get-TfsBuild
{
      [CmdletBinding()]
      param
     (
            [ValidateNotNull()]
            [Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]
            $TeamProjectCollection,

            [Parameter(Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [string]
            $TeamProject,

            [Parameter(Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [string]
            $BuildDefinition,

            [string]
            $BuildNumber
      )

      $server = $TeamProjectCollection.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
    if($BuildNumber)
    {
        $server.QueryBuilds($TeamProject, $BuildDefinition) |? {$_.BuildNumber -eq $BuildNumber}
    }
    else
    {
        $server.QueryBuilds($TeamProject, $BuildDefinition) |? {$_.Status -eq "Succeeded"} | Select -Last 1
    }   
}

PS C:\> Get-TfsBuild -TeamProjectCollection $collection -TeamProject $teamProject.TeamProjectName -BuildDefinition BlogsPrajeesh.Samples.Web_CI | select BuildNumber

BuildNumber
-----------
1.0.0.5  


Invoke-TestRun

A test run is the execution of test cases in a test suite or test case, to be executed against a specific configuration in an test environment. You also need to mention a TFS build to be used for the test run. For details on how to run tests in Microsoft test manager follow the article https://msdn.microsoft.com/en-us/library/dd286680(v=vs.110).aspx.

In our function, we will make use of the output from the previous functions created in this post to start a test run. Later we’ll create functions to get the result of a test run.
Function Invoke-TestRun
{
      [CmdletBinding()]
      param(
            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            $TeamProject,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            [string]$Title,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            $TestPlan,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            $TestSuite,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            $TestConfiguration,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            $TestEnvironment,

            [Parameter(Mandatory=$true)]
            [ValidateNotNull()]
            [Microsoft.TeamFoundation.Build.Client.IBuildDetail]$Build
      )

      $TestRun = $TestPlan.CreateTestRun($true)
    $TestRun.BuildUri = $Build.Uri
    $TestRun.BuildNumber = $Build.BuildNumber
    $TestRun.BuildDirectory = $Build.DropLocation
    $QueryText = "SELECT * FROM TestPoint WHERE SuiteId=$($TestSuite.Id) AND ConfigurationId=$($TestConfiguration.Id)"
    $TestPoints = $TestPlan.QueryTestPoints($QueryText)
    $TestPoints | ? { -not($_.State -eq "NotReady" -and $_.MostRecentResultOutcome -eq "Blocked") -and $_.MostRecentResultOutcome -ne "NotApplicable" } | % { $TestRun.AddTestPoint($_, $null) }
    $TestRun.Title = $Title
    $TestRun.Owner = $TestTeamProject.TestManagementService.AuthorizedIdentity
    $TestRun.TestEnvironmentId = $TestEnvironment.Id
    $TestRun.Controller = $TestEnvironment.ControllerName
    $TestRun.Save()
$TestRun
}
PS C:\> Invoke-TestRun -TeamProject $teamProject -Title "Demo Testrun2" -TestPlan $plan -TestSuite $suite -TestConfiguration $config -TestEnvironment $environment -Build $build


ObjectType            : TestRun
BuildDirectory        : \\TFSSER\TRUNK\1.0.0.5
State                 : Waiting
PostProcessState      : Complete
DateDue               : 1-1-0001 0:00:00
Statistics            : Microsoft.TeamFoundation.TestManagement.Client.TestRunStatistics
ErrorMessage          :
Iteration             : TeamProject1
LegacySharePath       :
Type                  : Unspecified
IsAutomated           : True
Version               : 1000
IsBvt                 : False
TotalTests            : 0
IncompleteTests       : 0
NotApplicableTests    : 0
PassedTests           : 0
UnanalyzedTests       : 0
TestMessageLogEntries : {}
Title                 : Demo Testrun2
BuildUri              : vstfs:///Build/Build/5
BuildNumber           : 1.0.05
BuildConfigurationId  : 0
BuildPlatform         :
BuildFlavor           :
DateCreated           : 1-1-0001 0:00:00
DateStarted           : 1-1-0001 0:00:00
DateCompleted         : 1-1-0001 0:00:00
LastUpdated           : 4-7-2015 9:33:00
LastUpdatedBy         : TeamFoundationIdentity instance 34352

Receive-TestRun

The receive test run method gets the results of a test run at a later point of time by providing a TestRun Id.

Function Receive-TestRun
{
      [CmdletBinding()]
      param(
            [Parameter(Mandatory=$true, Position=0, ParameterSetName="TeamProject")]
            [ValidateNotNull()]
            $TeamProject,

            [Parameter(Mandatory=$false, ParameterSetName="TestPlan")]
            [Parameter( ParameterSetName="TeamProject")]
            [int]$Id,

            [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="TestPlan")]
            $TestPlan
      )

    switch($PsCmdlet.ParameterSetName)
    {
        "TeamProject"
        {
            $TeamProject.TestRuns.Find($Id)
            break;
        }
        "TestPlan"
        {
            $TestPlan.Project.TestRuns.Query("SELECT * FROM TestRun WHERE TestPlanId=$($TestPlan.Id) AND TestRunId=$Id")
            break;
        }
    }      
}

Wait-TestRun

The wait run is invoked in conjunction with the Invoke-TestRun, to wait till the test run is completed. This is useful when you are using the Invoke-TestRun method as part of a Tfs Build activity.

Function Wait-TestRun
{
      [CmdletBinding()]
      param
      (
            [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
            [ValidateNotNull()]
            [Microsoft.TeamFoundation.TestManagement.Client.ITestRun]$TestRun
      )
   
    do
    {
            Start-Sleep -Seconds 5
            $TestRun = Receive-TestRun -Id $TestRun.Id -TeamProject $TestRun.Project
      }while($TestRun.State -ne "Completed" -and $TestRun.State -ne "NeedsInvestigation" -and $TestRun.State -ne "Aborted")

      $TestRun
}

$run = Invoke-TestRun -TeamProject $teamProject -Title "Demo Testrun2" -TestPlan $plan -TestSuite $suite -TestConfiguration $config -TestEnvironment $environment -Build $build | Wait-TestRun 



That will be the last method in our TeamFoundation.TestManager module. The functions in this module can be used in various stages of your Continuous Delivery pipeline specially during test execution phase. If you want the source code of the module, I’ve added this to my GitHub project at https://github.com/prajeeshprathap/Powershell-PowerPack/blob/master/TeamFoundationServer.TestManager.psm1.