Thursday, May 11, 2017

Migration-base vs State-based database development approach

There are two main approaches for the development of SQL databases:

  • Transformational (migrations)
  • State-based (states)

Transformational or migration-based approach

The idea of the transformational approach is based on database migration from one state to another. After first production release, we will assume that database has its the first state. This state is the starting point for further migrations.
Why do I think that the starting point for migrations should be the first production release? The answer is simple. While the application has not gone into the production stage, it does not make much sense to try to save entered test data. Keeping data complicates development and testing process on earlier stages of project delivery. In this case, it is better to re-create the database each time and insert reference and test data into it. 
The diagram below describes the migration-based approach:


In this method, developers concentrate on writing migrations (M1, M2 .. Mn) from one database state to another (S1, S2 .. Sn). There is a good example of this approach. It is EntityFramework's migration mechanism. For more information, you can navigate and check MSDN article https://msdn.microsoft.com/en-us/library/jj591621(v=vs.113).aspx.

State-based approach

This approach is based on the following paradigm: developers have to maintain the most current snapshot of the database structure. What does it mean? The most convenient way to explain this is to analyze the following example. Let's assume that we have the table below:

CREATE TABLE People (
    PersonID  INT NOT NULL PRIMARY KEY CLUSTERED,
    LastName  VARCHAR(255) NOT NULL,
    FirstName VARCHAR(255) NOT NULL,
    Address   VARCHAR(255) NULL,
    City      VARCHAR(255) NULL
);

At some moment product owner decided to add one more property to the People table. In migration-based world in this particular scenario developer has to create migration script with ALTER TABLE Statement, but in state-base world we need to follow it's the main paradigm, so we need to update table creation script with a new column. Please see below.

CREATE TABLE People (
    PersonID  INT NOT NULL PRIMARY KEY CLUSTERED,
    LastName  VARCHAR(255) NOT NULL,
    FirstName VARCHAR(255) NOT NULL,
    Address   VARCHAR(255) NULL,
    City      VARCHAR(255) NULL,
    Country   VARCHAR(255) NULL
);

So developer needs to keep database structure up-to-date and the tools will do all the work. Cool, right? One of such tools was introduced by Microsoft when they shipped Visual Studio database project.
Let's see how these tools work. On the diagram below, you can find database development schema used by Visual Studio database project.


Microsoft Database project and tools inside of it will be trying to sync the database with current database script. For more info about Microsoft Database Project use https://msdn.microsoft.com/en-us/library/xee70aty(v=vs.100).aspx link.

What approach to choose?

It is difficult to say which approach is better or worse for a particular project. Next, I will give some advantages and disadvantages of each approach, which in my opinion play a key role in the choice of the mechanism for developing a database on the project. And you can decide what is the best for you.

Advantages of migration-based approach

  • Understandable workflow of data migration
  • Full control on generated SQL-scripts

Disadvantages of migration-based approach

  • Need write the tool for deployment script generation or pay for existing one
  • Developer's onboarding process require more time for understanding how database upgrade works
  • The complex mechanism for keeping the database in the actual state. Developer has to revert database to valid state to perform migration because order of migrations is important

Advantages of state-based

  • Gives developers access to the current state of the database
  • It is easier to audit and view history of changes in source control
  • Force developers to keep actual state of the database in source control
  • Database script compilation, developers can identify issues with their code during compilation
  • Can detect if somebody did manual changes in the production database and sync it with actual schema in source control
  • Build-in mechanism for database refactoring

Disadvantages of state-based

  • Developers do not have a lot of control over deployment script generation
  • Poor support for user data migration
  • Additional review of generated script required, developers have to check generated script before deployment

Tuesday, May 9, 2017

PHP Composer installation: The openssl extension is missing

Composer installation


To install Composer on Windows you have to follow documentation https://getcomposer.org/doc/00-intro.md#installation-windows

The openssl extension is missing issue

During installation "The openssl extension is missing..." issues could happen. 


Installation tool helps you to identify php.ini file location. As you already understood, we have to do some modifications in php.ini file to fix the issue. If you have empty php.ini file, then just add following code there:

extension_dir = "ext"
extension=php_openssl.dll

Otherwise open php.ini and uncomment php_openssl.dll extension and specify correct directory for PHP extensions.

Monday, May 8, 2017

Capturing and logging unhandled exception in AngularJs

Everyone knows how important to capture and log unhandled exception in your code. Today we are going to learn how to do that using Angular. In addition, we will implement functionality, which will send unhandled exception to the server.

$exceptionHandler

According to AngularJs website example, it is possible to override standard behavior, but we do not want to do that because it is better to keep default implementation and create decorator, which will extend standard functionality. Please see code below:

(function () {
    'use strict';

    angular
        .module('app', [])
        .config(config);

    config.$inject = ['$provide'];

    function config($provide) {
        $provide.decorator('$exceptionHandler', myExceptionHandler);
    }

    myExceptionHandler.$inject = ['$delegate', '$window'];

    function myExceptionHandler($delegate, $window) {
        return function (exception, cause) {
            // Keep default implementation.
            $delegate(exception, cause);

            // Execute server side logging.
            // Need to wrap to try catch, to prevent infinitive loop.
            try {
                // Cannot use $http service because of circular references.
                $.ajax({
                    type: 'POST',
                    url: '/api/log/',
                    contentType: 'application/json',
                    data: angular.toJson({
                        url: $window.location.href,
                        message: exception.message,
                        stack: exception.stack,
                    })
                });
            }
            catch (e) {
                // Do nothing, browser will display message in console.
            }
        };
    }
})();

Resolving circular reference

The previous example uses jQuery for sending exception data to the server. What to do if you want to use $http?! The first idea, which comes to your mind is to write following code:

myExceptionHandler.$inject = ['$delegate', '$window', '$http'];

function myExceptionHandler($delegate, $window, $http) {
    // Code inside
}
This code will not work, because of circular dependency. Please find below code which resolves the issue:

(function () {
    'use strict';

    angular
        .module('app', [])
        .config(config);

    config.$inject = ['$provide'];

    function config($provide) {
        $provide.decorator('$exceptionHandler', myExceptionHandler);
    }

    myExceptionHandler.$inject = ['$delegate', '$window', '$injector'];

    function myExceptionHandler($delegate, $window, $injector) {
        return function (exception, cause) {
            // Keep default implementation.
            $delegate(exception, cause);

            // Execute server side logging.
            // Need to wrap to try catch, to prevent infinitive loop.
            try {
                // Using $injector to get $http service.
                var http = $injector.get('$http');
                http.post('/api/log/', {
                    url: $window.location.href,
                    message: exception.message,
                    stack: exception.stack,
                });
            }
            catch (e) {
                // Do nothing, browser will display message in console.
            }
        };
    }
})();

Code examples are uploaded to GitHub repository, please use https://github.com/aliakseimaniuk/blog-examples/tree/master/angularjs-exceptions link.

Monday, November 14, 2016

Set default filegroup for Microsoft Database project


1) First of all you have to create new filegroup. To do that add following file to your database project:

DataFileGroup.sql


/*
Do not change the database path or name variables.
Any sqlcmd variables will be properly substituted during 
build and deployment.
*/
ALTER DATABASE [$(DatabaseName)]
    ADD FILEGROUP [DATA]

2) Navigate to Database project properties in Visual Studio. -> Click "Database settings..."


3) Navigate to "Operational" tab -> Set default filegroup using combo-box with created filegroup on step 1.




Monday, September 12, 2016

QA: Decision Tables as specification-based test design technique

Let's start with definitions, per ISTQB glossary:
Decision Table Testing: A black-box test design technique in which test cases are designed to execute the combinations of inputs and/or stimuli (causes) shown in a decision table.
Decision Table: A table showing combinations of inputs and/or stimuli (causes) with their associated outputs and/or actions (effects), which can be used to design test cases.
This technique is using to test all possible combination of conditions, relationships, and constraints. Decision tables usually applied for the integration, system and acceptance test levels. Also, this technique could be used for component testing.
The table should describe relationships between conditions and actions.

Template of Decision Table:
Decision Table Template











Example:
Decision Table Example











At least one test case should be created for each column. The number of tests will increase in case of boundaries values in conditions. Boundary Value Analysis and Equivalence Partitioning are additional to the Decision Table technique

Type of defects: functional and non-functional defects

Wednesday, September 7, 2016

Setting up Visual Studio Code for TypeScript development


Install TypeScript compiler

To setup TypeScript on your computer, you need to setup node.js with npm. There is a good article, which will help you to do that, please find it using following link: Installing Node.js and updating npm. 
We just installed node.js and updated npm. So we are ready to install TypeScript on your computer. If you want you can install the latest build of TypeScript. To do that you have to run following command:

npm install -g typescript@next #install nightly build

Although you have the possibility to install nightly builds, I would recommend installing the latest stable version of the language. To do that type following command in cmd.exe and hit enter:

npm install -g typescript #install the latest stable version

Install Visual Studio Code with extensions


GulpTsLintVisual Studio Code

Visual Studio Code

Let's install Visual Studio Code first. You can download and install it from https://code.visualstudio.com.

TSLint

An extensible linter for the TypeScript language. TSLint supports:
  • custom lint rules
  • custom formatters (failure reporters)
  • inline disabling / enabling of rules
  • configuration presets (tslint:latest, tslint-react, etc.) & composition
For more info please use http://palantir.github.io/tslint/

To install TSLint extension: Open Visual Studio Code → Navigate to Extensions tab on left sidebar → Type 'TsLint' in search text-box → Install extension.


To make extension work you need to install tslint globally. To do that run in cmd.exe tool the command:

npm install -g tslint #installing tslint globally

Gulp Snippets

We are going to use Gulp to compile our TypeScript code, so let's install Visual Studio Code extension to help us with Gulp syntax.
Open Visual Studio Code → Navigate to Extensions tab on left sidebar → Type 'Gulp Snippets' in search text-box → Install extension.


Creating the project

First of all, you need to create the project folder. I will create mine with the name "TypeScriptBlog". Create the folder and open it in cmd.exe tool. Now we need to create package.json file. To do that run in cmd.exe command:

cd path/to/project
npm init

Open created folder in Visual Studio Code and check created file. It should contain something like this:

{
  "name": "typescriptblog",
  "version": "1.0.0",
  "description": "Blog engine written on TypeScript",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}

We are now ready to install the third party dependencies:

npm install  --save-dev typescript
npm install  --save-dev tslint 
npm install  --save-dev gulp
npm install  --save-dev gulp-tslint
npm install  --save-dev gulp-typescript

Compiling the project

Create gulpfile.js in the project's  folder and copy following  content to it:

var gulp = require("gulp"),
    tslint = require("gulp-tslint"),
    tsc = require("gulp-typescript");

var tsProject = tsc.createProject("tsconfig.json");

gulp.task("build-app", function () {
    return gulp.src([
        "app/**/**.ts"
    ])
        .pipe(tsc(tsProject))
        .js.pipe(gulp.dest("app/"));
});

// Rebuild project on any ts file changed
gulp.task('watch', function() {
  gulp.watch("app/**/**.ts", ['build-app']);
});

Create tsconfig.json file and copy following content to it:

{
    "compilerOptions": {
        "sourceMap":  true
    }
}

Now we can build our application. Press Ctrl + Shift + P in Visual Studio Code → Type "Run Task" → run "build-app" task. If you want to rebuild your code each time when any file changed, execute task with name "watch".


To test that the Gulp is working you can use following files. Create app folder in the root folder and add files to app folder.

greeter.ts


class Greeter {
    constructor(public greeting: string) { }
    greet() {
        return "<h1>" + this.greeting + "</h1>";
    }
};

var greeter = new Greeter("Hello, world!");
    
document.body.innerHTML = greeter.greet();

greeter.html


<!DOCTYPE html>
<html>
  <head><title> TypeScript Greeter </title></head>
  <body>
    <script src='greeter.js'></script>
  </body>
</html>

Project structure



Linting the project

Earlier we installed all necessary tools for linting. Now it is time to configure them. Open cmd.exe and execute command:

cd path/to/project
tslint --init

After that you can find that tslint.json file was added to the solution. This file contains default linting settings, if you would like to extend or change them, please use https://palantir.github.io/tslint/rules/ for more info.
One more thing what we can do. We want tslint be executed using Gulp, so open gulpfile.js file and add the following code to it:

// Linting the project
gulp.task("lint", function () {
    return gulp.src([
        "app/**/**.ts"
    ])
        .pipe(tslint({
            formatter: "verbose"
        }))
        .pipe(tslint.report())
});

If 'lint' task does not appear in the task list, restart Visual Studio Code and try again.

Сonclusion

Now we know how to setup Visual Studio Code with TypeScript. With this article, I open a cycle of articles about TypeScript, in which we are going to create blog engine written on TypeScript. All the code you can find under repository https://github.com/aliakseimaniuk/TypescriptBlog

Thursday, September 1, 2016

QA: Boundary Value Analysis as specification-based test design technique

Let start from definition, per ISTQB glossary:
Boundary value analysis (BVA): a black-box design technique in which test cases are designed based on boundary values.
 Boundary Value: an input or output value which is an the edge of an equivalence partition or at the smallest incremental distance on either side of an edge, for example the minimum and maximum value of a range
This technique is an extension of equivalence partitioning technique.  There are two approaches of BVA exists:
  • Two values testing.  Only two values selected for each boundary: one value on the boundary and the previous/following value outside the partition. For example, if an equivalent partition is integer range from 10 to 15, the following values should be tested: 9 (outside of the partition), 10 (boundary); 15 (boundary), 16 (outside of partition). Short description: MIN-1; MIN; MAX; MAX+1; Where "1" is the minimal incremental value
  • Three values testing. This approach uses 3 value as the basis. One value outside of the boundary, the second value is boundary value, and the third value is inside of partition. For example, if the equivalent partition is an integer from 10 to 15, the following value should be tested: 9 (outside of the partition), 10 (boundary), 11 (inside of boundary); 14 (inside of boundary), 15 (boundary), 16 (outside of partition).Short description: MIN-1; MIN; MIN+1; MAX-1; MAX; MAX+1; Where "1" is the minimal incremental value 
Which approach to select? The approach should be selected based on Risks which are associated to tested items. 3-values approach should be selected for the highest risks.
VBA could be applied for ONLY for ordered equivalent partitions. Type of ordered equivalent partitions:
  • Numeric attributes of non-numeric variables (e.g., length) 
  • Loops, including those in use cases 
  • Stored data structures 
  • Physical objects (including memory) 
  • Time-determined activities

Type of defects: functional and non-functional