Translate

Wednesday, 15 May 2019

CI/CD - Travis, Jenkins, GitHub, Cloud, DevOps

DevOps is the latest sensation happening in the software development realm not just because of the fascinating array of tools that need to be used to implement a SCM strategy but in the immense challenge that it presents to teams that are on the Agile way of software development.

In frameworks like SAFe, that has a systems view, the importance of DevOps is immense especially when SAFe could encapsulate Behavior Driven Development (BDD), Test Driven Development (TDD), Scrum, XP, Kanban in itself to deliver a solution.

There are many ways of integrating code in a SCM repository but the key factor is in selecting the right tools to have an efficient set of pipelines to enable all aspects of the Agile Software Development Lifecycle.

Traditionally, Continuous Integration(CI) means checking out, checking in, committing code and to ensure that the build always succeeds and the code base is clean for the entire team to use, whenever, wherever and whichever tool they want to access the code from. However, things are not as hunky-dory as it looks because when you check out the tools that are available in the market, including the Cloud based ones, they appear to be free and easy to use so, at first glance, it does look all rosy.

For instance, Jenkins has a cool interface that clearly tells the user on which SCM repo to use.



But the real trick is in enabling the access to the SCM for the tool.

Jenkins is an integrator that works on a different machine from the one where your code is hosted - eg., GitHub and so authenticating the CI tool to access the repository's status, code, scripts important and since Jenkins is a separate server by itself, credentials cannot be passed as is. So, what is required is for a secret that only the two tools know so that they could authenticate against a key generated using a standard cryptographic algorithm like a SSH key.



The same key is with the GitHub repository as part of your configuration of the GitHub account.



The difference between the various tools like Jenkins, Travis, Azure DevOps etc is in the way your build configuration is expected to be.

In Travis, for example, the travis.yml contains all the build steps in the form of a yaml script, which means that as long as the virtual machine understands the script, you can just about configure anything, from code coverage to tests to installation of npm packages or not, to running a mongod instance and test results as an Istanbul report, for example.

This configuration script is expected by Travis to be part of your code repository to which it is synchronized with. If there is no travis.yml then Travis will default to Ruby.



The travis.yml contains the script that tells the Travis CI container how to run the build.





And the travis.yml script does many things like installing nodejs packages (which can also be set to ignore with a gitignore file in the repo), connecting to a mongodb instance and importing some json data to running a mocha test and providing a code coverage report.

Jenkins, on the other hand, provides for the build environment, build triggers and build actions and post actions within its interface. And since Jenkins gels well with Maven and the Java environment, its usage requires a good knowledge of the Java development tools, environment like maven, the JDK and the scripts to execute the build.





But unlike Travis, which is more suited for open source projects, Jenkins is a more specialized CI tool.

The commonality in all DevOps tools is in the integration of a CI tool with a SCM repository and with a Cloud storage container to enable Continuous Deployment (CD), the usage, though, will differ as per the depth in the software development process of the team.

Below are some important questions that could serve as a checklist when deciding on what kind of a DevOps environment that you want setup for your organization/team?
  1. Does the team wish to map its BDD or TDD into an automated environment?
  2. Is there an automated build that is wired with the testing framework and the code coverage tool ?
  3. Are deployments to the cloud monitored or automated and to what extent is quality ensured in the release to deploy?
  4. How often is the release to deploy planned?
  5. What are the planned pipelines in the build that cannot be ignored or skipped and who are the responsible members in the team?
  6. Does the responsibility or accountability in anyway compromise the agility in the team?
  7. What are the recovery mechanisms or policies in place for the CI/CD pipelines?
  8. To what extent does the organization want traceability from requirements to deployment?
More on the DevOps Deployment stage in the next post.

Friday, 3 May 2019

The Chess Tournament Standings table - jest-cucumber, react

A Chess tournament standings table is a good case study to implement a simple react component that stores data as part of each cell so that 

 Chess.com

as and when the players move up or down the table, as per their match position, the individual game score against individual players is maintained in each cell. 


This means that each cell stores data as 

cellData={gameResult: 0, 1/2 or 1, opponent: 1-maxNumberOfPlayers, points: totalMatchPoints,}

This is the simple business requirement that is to be delivered as a product utility for a chess website like, say, Chess.com.

As a first step, we find the entities that interact with other in this system, the responsibilities of each entity and the relationships.

The first entity is, of course, the results board. What are its responsibilities?

Primarily, it should display/reflect the latest status of the tournament.

Upon the completion of each round, its status should show an updated, latest positions of the players.

Does the board itself do the display and the update?

Since in a real life scenario, results boards are maintained by a score keeper, let the score keeper be the entity to manage and maintain the positions and the scores of the players.


The business requirements and the model are clear.

I will use Behavior Driven Development (BDD) to convert the business requirements to a technical blueprint so that the initial analysis of all the scenarios are done and if any discrepancies, the cost of change would not be as high if we had simply allowed the development to happen without doing the tests of the business cases.

Using gherkin syntax to write the feature, we have

Feature: Results board
Scenario: Maintain each player's score in relation to each opponent played and total score
Given a player is playing in the tournament, the board should have a row representing each round
played by the player
Then the board row should be visible with a cell for each round

Note that there is no when clause yet. This is because we have no action present in the system. We are only looking for the business rules and whether they are testable.



Here is the CodePen for this initial code state.

Proceeding to the next step, Test Driven Development (TDD) is clear.

The first test case is "Is each player represented as a row in the board?" Not yet.

Question: What are the data required to make this test pass?
Answer: We need the number of players participating in the tournament and max rounds to be played by each player. 

Currently, we have a default number of max rounds played as 10, with 1 cell for total score and 1 player.

This is the simplicity and clarity that BDD provides when translating requirements to code and the design evolves through each test. 

Thursday, 4 April 2019

BDD with Jest + Cucumber & Typescript

Continuing on the previous post on the Tesla Auto Pilot crash mode malfunction, here is a working code example of the feature.

The advantage of BDD is that you can not only keep the business engaged in the development process but also ensure that there are no disputes nor any cost of change as every business requirement gets neatly described as features from which all the possible scenarios based on business rules can be elaborated into crystal clear test cases.

The other advantage, of course, is that Test Driven Development becomes easy to implement as the BDD phase effectively outlines just those test cases for code to be written against for the feature to be realized.

Here is the example scenario of the auto-pilot mode beeping if the car is in auto-pilot mode.

So, effectively, there are two scenarios for the feature test to pass -

1. The car should be on auto-pilot mode.
2. The beep should be set on only if the auto-pilot mode is on and there is an object ahead.

Remember that BDD is about testing scenarios and so we don't have asserts but expects.

npm Packages used: jest, jest-cucumber, typescript, babel
Platform: nodejs
Dev tool: VS Code
Language: English :), typescript

jest-cucumber, by default, checks all tests defined under a _tests_ folder and if one does not exist then it follows the path given in the config file or in the testMatch in the package.json file.

The feature is clearly described in a .feature file as below. Remember that the gherkin syntax of given, when, then should match the scenario described in this .feature file.


The gherkin steps are defined in the .steps. file.



The actual code to test the expectation is the source code as below:


Run the test with jest.



Now, change the scenario description.





and running the test would cause the test runner to display errors because the scenario text has changed and does not match the scenario being tested for in the .steps file.


Similarly, if the source code running the test is changed and the distance is not set, then, too, the test will fail because expectations are not met!


The code change is the commented call to the method that sets the object ahead's distance (hypothetical) and so the test will fail when it tries to match the distance between the car and the object ahead.


Similarly, if the auto-pilot mode is not set the test will fail as that is the base scenario test!

From the above, you can easily perceive that the advantages of using jest-cucumber for BDD are obvious and numerous.
  1. Business can easily stay on track with development efforts.
  2. Wastage in effort and time as well as cost is reduced due to the traceability of requirements to code and vice-versa.
  3. Code waste is reduced. Only that much code is written in the TDD phase as defined by the BDD phase.
  4. Audits become simple because of the end-to-end testing available with one click.
With scaled agile frameworks like Safe, which require BDD and TDD to be well implemented, jest-cucumber and jest are incredible tools to infuse maximum agility into the software development process.

Of course, this is not to say that other tools like SpecFlow that are used for other frameworks like .Net or Java are not good, they all serve the same purpose - of defining features, deriving scenarios, writing test cases either in gherkin form or otherwise to automate the testing of your system.

Binding the test results from the above phases along with Selenium or Acceptance/Functional tests with test coverage completes the automated requirements for DevOps.

Happy BDD-ing! :)

Sunday, 24 March 2019

BDD + UADD (also known as ATDD)

It was a long time ago that I introduced UADD to an Agile audience in a Delhi NCR Agile conference (Here is the link to the presentation) but I still remember a few reactions like, "What is UADD? We have never heard of it". It told me a few facts of the world; technology, techniques and tools are not adopted as per requirement or need but on the basis of terminology that is popular, at least in India.

Almost ten years later (during which time not one in any project that I worked on was there a mention about BDD or UADD), I came across this project that used Gherkin, Cucumber and jest to drive a BDD + TDD project but the scenarios were not elaborated as tests, which is what you can do if you use jest-cucumber.

So, here we are, I thought to myself, a completely wired, end-to-end testing tool that I had envisioned a decade back using Slim and NUnit - the tools then were obviously lacking in many respects - to increase visibility of requirements as planned and to help tracking them as the project moves forward is popular.

This made me think that now is the time to take BDD to the next level.

BDD or Behavior Driven Development is a software development technique to address requirements in an easy-to-read, conversational description of a product feature and scenarios, with steps outlined, to help complete the realisation of the feature.

But BDD or rather its form, can also be used in a non-software development context.

For instance, there was this recent BBC review of a self-driven car of Tesla that showed how the auto-pilot in the Tesla could not detect a stationary car ahead of it and crashed right into it because another moving car ahead of the Tesla had been blocking it till it swerved away at the last moment.

This demonstrates the classic lazy testing syndrome - the positive scenarios are tested but the negative ones are not - often seen with teams that are pressed to deliver or does not have deep experience in testing a system

With the BDD language, you are provided with a mechanism to put the scenarios down on paper for better visibility and due to its language, in a conversational tone, proper communication happens across the system to convey what needs to be tested because when the behavior of the system is under test then the stakeholders range from business to laymen who do not understand the technical jargon.

Let me elaborate how BDD helps in the Tesla scenario

Scenario 1
Given
the car is in auto-pilot mode,
When a stationary car is ahead (distance not mentioned in this scenario)
Then brakes should be applied or an alert should be sounded

Scenario 2
Given the car is in auto-pilot mode,
When a stationary car is ahead at a distance of 10 meters (distance mentioned in this scenario)
Then brakes should be applied or an alert should be sounded

Scenario 3
Given the car is in auto-pilot mode,
When a stationary car is ahead at a distance of 5 meters (distance mentioned in this scenario)
Then brakes should be applied or an alert should be sounded

Scenario 4
Given the car is in auto-pilot mode,
When a stationary car is ahead at a distance of 3 meters (and so on)
Then brakes should be applied or an alert should be sounded

BDD is about establishing a communication with all the stakeholders in the system under development. It is all about increasing collaboration between all the stakeholders including the customer.

In the above example, it is so clear that any inexperienced person in the team may conclude that scenario 1 is all that is needed and a little more experienced may conclude that the four scenarios completes it but not so.

The biggest anti-pattern when using BDD is to write the scenarios in isolation.

The four scenarios, especially from 2 - 4, highlight the fact that a base scenario of applying instant brakes when any object, stationed at any distance less than already tested for, from the self-driving car, completes the quality assurance required.