Types of Software Tests

Software testing types

Industrial production of software means the product has to go through tests in all possible ways in order not to fail when the hard times come.

Unit tests

In broad perspective this means that code has to be separated by units and these units have to be covered by all possible conditions in which code will get. Properly written unit tests help to speed up development and release processes.

  1. Firstly, when developers change some part of the application, unit tests will say immediately where and what is failing in other parts.
  2. Secondly, failed tests on build say that app is not ok and can’t be delivered as it is.
  3. Thirdly, the way units tests can be applied forces developer to write easy understandable and maintainable code.

    [code language=”groovy”]
    package com.application

    import grails.test.mixin.TestFor
    import spock.lang.Specification
    import spock.lang.Unroll

    /**
    * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
    */
    @TestFor(Book)
    class CampaignSpec extends Specification {
    @Unroll
    void "test maxSize constraints #propertyName, #size, #error"() {
    given:
    mockForConstraintsTests(Book, [])
    def book = new Book()
    book.setProperty(propertyName, ("x" * size))
    book.validate()

    expect:
    error == book.errors[propertyName]
    where:
    propertyName | size | error
    "name" | 36 | null
    "name" | 127 | null
    "name" | 128 | "maxSize"
    "pk" | 5 | null
    "pk" | 15 | null
    "pk" | 30 | "maxSize"
    }

    }
    [/code]

Integration tests

Some times it’s not possible to write units tests because part of the code relies on third party APIs or services. This is especially relevant when using AWS or Microservices architecture. There are ways of creating local replicas. However, they do not work exactly the same as native ones. For example, downloadable Dynamo DB version for local machine is not supporting Tagging whether native is.
For that case developers use integration tests where App in testing environment behaves exactly the same as in production. This helps to achieve several goals:

  • test in vitro. Means to have a look how app behaves in close to prod conditions.
  • test App with these service which are not Mockable and it’s not possible to create local replica.
    If third party changes something in their API, integration tests will immediately show this spot in the app.

    [code language=”groovy”]
    package io.aws

    import javax.servlet.http.HttpServletResponse

    class S3HelperServiceFunctionalSpec extends IntegrationSpec {

    @Shared
    def amazonWebService

    void "test remove folder with it’s content"() {
    given:
    String bucket = "bucket"
    String key = "s3key"
    when:
    s3HelperService.removeFolder(key, bucket)
    ObjectListing listing = amazonWebService.s3.listObjects(key, bucket)
    List<S3ObjectSummary> objectSummaries = listing.getObjectSummaries()
    then:
    objectSummaries.size() == 0
    }

    }
    [/code]

    Human testing

    This is one of the key roles in commercial success. Good QA worth a lot. One of the reason is that developers usually do not think like users and click only what they need in this particular case. Moreover, psychologically if they feel it can brake in this spot or other they would avoid checking it. QA on the other hand will try to brake it in every possible way. This is especially relevant to customer facing apps.

    Remember, it is better to spend more on testing than dissatisfied customer.