Continuous delivery, Tips & tricks

Ustawianie numeru wersji w .NET… i to bez AssemblyInfo.cs

Programiści .NET od zamierzchłych czasów używali podmiany wersji w pliku AssemblyInfo.cs do uaktualnienia wersji tworzonej aplikacji. To było oczywiste jak stawianie średnika na końcu linii. Jednak czasy się zmieniają, mamy nowe CLI i warto wiedzieć, że można łatwo zmienić numer wersji aplikacji bez dodatkowych narzędzi ani skryptów.

Continue reading

Advertisements
Continuous delivery

CICD na sterydach: deploy pull requesta jeszcze przed jego zamknięciem

Czasem robiąc code review rodzą się wątpliwości, czy dany kawałek kodu w ogóle działa albo czy przypadkiem nie psuje reszty systemu. Najlepiej w takiej sytuacji przed zamknięciem pull requesta po prostu to przetestować, ale do tego trzeba ściągnąć najnowszą wersję kodu, zbudować i uruchomić projekt a wcześniej odłożyć swoje zmiany na bok. Sam wiem po sobie, że często z tego rezygnowałem. Można jednak rozszerzyć swój proces CI/CD aby build server sam robił deploy każdego pull request’u na odrębne środowisko.

Continue reading

Continuous delivery

Continuous Integration vs Continuous Delivery vs Continuous Deployment

Wiele razy słyszałem jak ludzie mylą Continuous Delivery z Continuous Deployment dlatego zdecydowałem się tutaj pokazać różnice, zaczynając przy okazji od Continuous Integration. Bez obaw, postaram się unikać słownikowych definicji.
Wyobraźmy sobie, że chcemy ocenić poziom zaawansowania procesu wytwarzania oprogramowania jaki obowiązuje w naszym projekcie. Możemy tu wydzielić następujące etapy:

Continue reading

Continuous delivery

Code inspection on build server using ReSharper Command Line Tools

Did you see source code with VS scrollbar full of different colors and warning sign in every file? For a long time that was my case. It did not help that we agreed on some coding guidelines within our team. If some rules are not enforced, then code issues will get into your source code – doesn’t matter if it’s rush, manual refactoring, merging conflicts or less careful teammates. To avoid that the best way is to make code inspection part of your bulid pipeline.

Continue reading

Continuous delivery

Why to do automated UI tests?

imageWe live in the time of TDD and unit testing. We already know that it’s one of the best practices so we do it in hope that it solves most of our problems. But is unit testing really enough? If you feel it’s not, and have heard of other types of test automation, but you’re not sure if they are for you, let us think it over together.

 

 

What is test automation

Test automation is all about reducing repeatable manual testing effort by automated scenarios. Manual testing (in web application) is checking if page looks OK in different browsers, checking if JavaScript code runs correctly, data is persisted to the database, there are no performance hits, email sending mechanism does its job etc.. These scenarios can be both recorded or coded. It is not only about UI testing (with Selenium or WatiN). In testing environment exists the term of “test automation pyramid” (by Mike Cohen) that places different kind of automated tests on specific level according to it’s complexity (the higher the more complex) and number of tests (the least number on the top).

Common arguments

The most common argument for test automation is that it reduces the cost of testing. It’s how people perceive this kind of practice. And indeed, hours of our manual clicking through the system (especially if you do not have dedicated tester) costs a lot, and in the same time you could do something considerably more valuable. Test automation gives you faster feedback after finishing some feature – automated tests should run in a few minutes and tell if it’s done or by doing one improvement you broke three other parts of the system.

As long this is pretty common understanding, it’s sometimes not enough for people who are not struggling with such problems because they are not doing regression at all (very common problem which is even worse than long and expensive manual regression).

Among this we forget about few more important arguments for test automation, especially from developer’s perspective.

Most important benefits

1. Test automation enables high level refactoring – the most basic rule behind TDD is: red, green, refactor. And you might have felt that because of unit testing you were able to refactor the code. But unit testing is about a good design of project, not about the best refactoring. Low level testing allows low level refactoring and high level testing allows high level and exciting refactoring.
My teammate and I have a list of expensive refactorings that we want to do if we have time – we call it “wishlist”. Several items from the top: upgrade NHibernate, upgrade jquery, upgrade jquery ui, css cleanup, clean up db objects, remove legacy ORM etc.
Does unit testing allow us to realize all of these wishes? Of course not. But thank to UI testing we can refactor the UI part – jQuery, CSS etc., due to acceptance tests we can fix business logic, due to integration tests – upgrade external libraries and so on. This is the most exciting ability that test automation gives to developers.

2. Test automation enables continuous delivery – continuous delivery is amazing because we can get feedback from the user in a very short time. It means that the team needs to deliver frequently and it’s obvious that every deploy to production needs to be preceded by a lot of testing. Without test automation it’s even impossible to proceed with such a practice.

3. Test automation stabilize regression – the first question is – do you have a proper regression scenario? I’d bet in most cases it’s like that: for the next “X” amount of time everyone is testing the system. Do we know what to test? Are we sure that we do the same regression as for the last time? No, because manual work –  deployment or testing – is error-prone. We do not like going step-by-step through the manual. In contrary – computer likes it. What is possible to automate should be automated.

Summary

As you can see there are many pros to test automation. Why isn’t it as common as unit testing? The answer is simple – it’s hard to work out proper test automation solution, and in opposite it’s considerably easy to set up very bad and impossible to maintain test automation that discourages managers from further investment in such practice. But of course it’s worth trying.

In future I’m planning to write more about rules for writing good and stable automated tests.

Articles, Continuous delivery

Dev-team Awesomeness Quiz. List of development practices.

Hero-Envy-SupermanThis quiz is to let you evaluate your team/project in terms of good practices. Below you will find a list of different development practices/techniques. Mark the practices you use in your project and sum the points assigned to each technique. Then you can place yourself on the right place on the awesomeness scale. Be frank with yourself – don’t mark “UI testing” if you have one UI test that produces unknown result or “Friday (20% of time)” if you once stayed longer at work to do some refactoring.

Questions


Name
Description Points
Source Code Versioning Using SVN, Git, etc. (instead of shared disk space) 2
Using build server Separated machine compiling the solution, running tests and publishing the results 2
Automatic versioning Assigning application version by buildserver 1
Clean build No warnings while building the solution 1
Code quality rules Having and following a list of code quality rules checked by buildserver. Build fails if not passed 1
Code quality metrics Measuring “code coverage”, number of lines of code, number of unit tests, cyclomatic complexity 1
Separated tester role Having a tester whose only responsibility is testing the quality, doing regression tests etc 1
“One click” deployment Using WebDeploy or any other script that lets to deploy the software in less than few clicks 1
Continuous delivery Continuous integration + automated testing + continuous deployment 2
Database upgrade script Database migration is done automatically as part of deployment 1
Database refactoring Database is refactored, there is no left stored procedure/table, no “obsolete” fields 1
Pair programming Two developers + one computer 1
Code review Each commit/functionality is reviewed by another developer 2
External code audits Code review done by developers from the outside of the team 1
Friday (20% of time) Every month/week/”on Friday” stop doing productive staff and hold on to refactor something 1
Maintain central documentation, wiki Describe important information/workflows in one place and keep updating 1
Work agile Contact with client, work in iterations (not only Scrum) 1
Unit testing Non-production code testing small parts of production code 2
TDD Test-driven development: write test, write code, refactor 1
ATDD Specify requirements as automated tests 1
BDD Test whole behaviour not just parts of code 1
Discuss BDD scenarios with customer Customer utilise BDD scenarios, they can be written with specific language (i.e. Gherkin) 1
Non-back-end unit testing Unit testing of other parts of source code, for example JavaScript 1
Automated UI testing Automated tests of scenarios using user interface, using tools like Selenium, WatiN/WatiR 1
Performance testing Load tests, stress tests, analysing reports 1
Integration tests Automated testing of integration with other systems (i.e. exposed service endpoints) 1

Summary

1. [0 – 5 points] Ok, this is probably one-man academic project or a simple website. But at least you have found this list of ideas. Each month peek one and try to experiment. The benefits are invaluable! The great pleasure of seeing the build server full of green signs of passed tests… Can you imagine the feeling of safety when refactoring your code or UI? The instant feedback from users and the awesome feeling that you and your project are awesome and can be mentioned as an example to follow. This all is a bread and butter for mature teams.

2. [6 – 11 points] Is it that you are willing, but you don’t have time? No one does. Is your project too small? Notepad.exe has more that 200 UI tests. Think, that the next person that will take over your project in the next 6 months is a serial killer that knows your address.

3. [12 – 18 points] This is great that you came to this point. You passed the test. But be aware of the fact how many things you can improve. Remember that there are better projects, easier to maintain and refactor.

4. [19 – 25 points] Excellent work. This level is sometimes the maximum for some projects. Your team/project rules. People can actually mimic your way of working, I’m not telling that you must go now ask for a rise, but of course you can try :]

5. [25 – 31 points] You are simply awesome. You’ve reached the top. You are like Chuck Norris in development Texas and you turned “GodMode” in your project. Keep it up. PS: Do you still remember about earning money?

Final note

This was just my proposal of practices used by developers. It’d be fabulous if you add your ideas in the comment. I promise to add best ideas to the list!

You can also share your score if you want.

Continuous delivery, Programming (back-end)

Get value of Selenium IWebElement

Introduction

Selenium.WebDriver (SeleniumHQ) is a great tool that lets you automate your Web UI Tests. With the tool you can navigate through web pages, find elements, put text into input controls or click links or buttons placed in that pages. Unfortunately as life shows, you can always find some lacks. The lack of element’s value getter is one of them.
 

Example scenario

You build a system where the user can enter data in some popup dialogs. The obvious test you may write will be the test for saving the given data, but another one may be the test checking that after saving the data and reopenning the form all the fields are empty again. Unfortunatelly you cannot use the Text property getter, because you are dealing with the INPUT control (which moreover is changed by JavaScript thus the DOM’s innerHtml property is not set).
 

Solution

You could say that unless the element were IWebElement in Selenium.WebDriver but mere DOM object you could get it’s value using javaScript, i.e. jQuery val() function. Happily Selenium.WebDriver provides a way to execute javaScript in the browser. The idea is to make the element identifiable and execute a script that finds the element and gets the value. Here’s my implementation of that idea (I have put everything to C# extension method):
public static string GetValue(this IWebElement element)
{
//Ensure that there is are identyfiable elements
Contract.Requires(element != null);
Contract.Assert(String.IsNullOrWhiteSpace(element.GetAttribute("id")) == false,
"Empty element 'id' attribute");

//Build selector to get the element by the browser
var cssSelector = String.Format("{0}#{1}",
element.TagName, element.GetAttribute("id"));

//Get WebDriver to look for elements and execute javaScript
var webDriver = ((RemoteWebElement)element).WrappedDriver;

//Ensure that the javaScirpt script finds the exact element
var foundElements = webDriver.FindElements(By.CssSelector(cssSelector));

Contract.Assert(foundElements .Count == 0, 
"No element found using the given selector");
Contract.Assert(foundElements .Count > 1, 
"Unique ID constraint violated for the element");

//Build and execute the javaScript
var script = String.Format(@"return $(""{0}"").val()", cssSelector);
return ((IJavaScriptExecutor)webDriver).ExecuteScript(script) as string;
}
 

The design-by-contract programming takes considerable amount of code here but the idea remains simple. The javaScript line is written as jQuery code but if you want you can write here anything that obtains the element’s value.
 

Disadvantages?

The most fragile part of the solution is grabbing the element. There must be a way to identify it with javaScript – I used element’s ‘id’ attribute because it’s simple, but you can construct XPath expression or anything you want to do that. If you test the software you create, you can always influece the way the element was created and predefine the identifier. For autogenerated elements you may provide a way of getting the element using XPath or your own way of getting the descendant of another identifiable element.
What about performance – are we looking for the same element twice!? Yes, but this could takes miliseconds while the whole session of UI Tests could take tens of minutes. The waste of time is repaid by the new functionality coverage.
 
Happy UI Testing!