Translate

Saturday, 18 May 2019

Automating BDD ...

...with Jenkins, typescript, jest, Jest-Cucumber on node.js

Assumption: Jenkins and NodeJs installed in your local machine.

Continuing with a previous post on BDD, this post is on using your GitHub repository as the SCM provider for Jenkins to build the scenario tests written using the Gherkin syntax of given, when, then and executing the tests, written in Typescript, using jest-cucumber on Node.Js!

The scenario is

  1. Your development and the business teams are located distributed across the world and you are managing the entire development process remotely.
  2. The development team waits for the BDD process to pass the requirements by runniing scenario tests to test the business rules.
  3. This post elaborates how to setup the BDD environment so that all features envisioned by the business owner are first tested with appropriate acceptance criteria and if the tests pass then the next phase, TDD, begins.


The above scenario assumes that the features, written in Gherkin syntax, are uploaded to a GitHub repository (This one is named bdd-travis although this is a Jenkins example, because I had used this repository with travis so the name is so!)

First step, is to tell Jenkins that you are going to build a NodeJs app.

Configure your Jenkins project to include a NodeJs plugin - Jenkins->Manage Jenkins -> Manage plugins and select the NodeJs plugin.

Once the plug in is installed, navigate to the Manage Jenkins page and click on Global Tools Config




and add a new NodeJs installation and your Jenkins page should like in the above screenshot.

Once the nodejs installation is complete, head to your project and select Configure to configure the GitHub repo details for Jenkins to process the Continuous Integration with the BDD repository.



and specify the GitHub repository URL.


Next step is to configure the access for Jenkins. Click on the Add button next to Credentials and select SSH username with password. 


Enter your GitHub username and a private key. This private key is the SSH key that you could obtain from any SSH rsa 2 generator like Putty that will give you a public and private key.

Enter any passphrase that you may have created while generating the SSH key.

Next step is to add the SSH key in your GitHub repository.



Note: The above steps of adding the SSH key is optional if you are simply using your local machine.

Once everything is set, your Jenkins dashboard show up the files from the GitHub repository in the project workspace.



Now to build the workspace.



Under the Build tab, select the Execute Windows batch command under Execute NodeJs Script. The check will let you know that there is a NodeJs installation in your Jenkins.




Type "npm test" into the textbox - the same command that you will use on your local NodeJs command prompt to run the Package.json test script and click Save.






Of course, for first time, you may want to run "npm install" to install all nodejs packages required by your GitHub repository.

Remember, the execution of the project will happen in your local machine (or the machine/Docker/Cloud storage where you have installed Jenkins).

Now, browse back to your project in Jenkins and click Build now.


Once the progress bar completes, click the down arrow next to the build # and click Console output





The Jenkins workspace will now refresh itself with any changes made to the GitHub and so, as and when newer features are tested with scenario tests, Jenkins will run the tests.

So, as a remote product owner or a stakeholder,  all you need to do is run the Jenkins build and check out the results and approve the new features. 

And a remote development team, waiting to start its TDD process based on the passed (Approved features), would simply pick the baton and sprint towards its goal of delivering a marketable feature frequently and fully tested!

Happy Automating BDD ! 😀😁😃

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! :)