Uploading CSS files using “Shrine” gem

I have recently switched from carrierwave to shrine in my Rails app and i thought i follow the advice of Alan Richardson, saying when you learn something new, irregardless of how trivial it might seem to you, share it and save someone else that headache.

So in the Yangah application, we upload a number of files to amazon s3 which include images, font files and css files for these fonts. However, i have found that with shrine, out of the box it was not able to correctly set the mime type for the uploaded file on s3.

I actually did try to fix this myself and eventually reach out to the Shrine google group and Janko, the author of the Shrine gem was able to provided a suggestion which worked first time and i am grateful for that.

Here is a link to the actual thread but just incase it gets deleted; this is extract of the message sent by Janko.

The `determine_mime_type` plugin uses the “file” utility by default for recognizing the MIME type, and it seems to recognize .css files as “text/plain” (and it’s the same for .js files). As noted in the `determine_mime_type` plugin documentation, one analyzer won’t be able to correctly detect correctly all types of files.

For text-based file formats (non-binary) it’s probably better to use the “mime_types” analyzer, which uses the mime-types gem to determine the MIME type from the file extension directly (rather than file content). So you could built a custom analyzer that mixes and matches “file” and “mime_types” analyzers; trying the “file” analyzer first, and if the best MIME type that it could come up with was “text/plain” (which is technically correct), then you can call the “mime_types” analyzer to determine which text-based format is it exactly.
This way you still get the benefits of the `file` utility preventing someone from uploading a binary file with a .css extension, and use the precision of determining from file extension when needed.

I installed the gem “mime_type” and update the FileUploader class with code snippet below.

plugin :determine_mime_type, analyzer: ->(io, analyzers) do

mime_type = analyzers[:file].call(io)

mime_type = analyzers[:mime_types].call(io) if mime_type == “text/plain”

mime_type

end

 

And that’s it!!! i have the css file now being uploaded correctly with the mime type of “text/css”.

 

 

 

 

Posted in Programming | Tagged , , , , , , | Leave a comment

Testing an Asynchronous System – Part 2

In this post, I would like to consider how to write automated tests for negative scenarios
for a system built using an asynchronous / event driven architecture. In my previous post, i have mentioned,
that these systems are peculiar because the effect of the “write” actions are not immediately stored
in the persistence layer of the application under test.

As an example, in the current system which i have been testing on the write side of the application, the write commands traverses
though the Command API layer, the command controller layer and the command Handler layer before it ends up in the Event Store.
Once data reaches the Event Store, it is almost certain that persistence would eventually happen. i.e. there isn’t much that could go
wrong at the stage except things like infrastructure break down.

For End to End tests, what we would usually do is

SendAPostRequestToCreateOrUpdateAnEntity()
QueryAndWaitForEntityToBePersisted()

This usually works for happy path test scenarios but in a case where the test condition is that the Post Request should fail.
In the current system that is being referred to:

Business rules/Complex Logic checks is usually implemented at the Command controller Layer so if I want that I cannot persist a set of attributes because it
does NOT comply to some set of business rules, a naive way would be to write:

SendA,InvalidPostRequestToCreateOrUpdateAnEntity()
QueryAndWaitForEntityToNeverPersisted()

This 2nd line would never fail because immediately the test code executes that line, because of the nature of the system,
even if there was a bug in the system, we do NOT expect the value to have been persisted on first pass through the wait loop.
In fact, in an environment where Test driven development is being practised, we expect our tests (unit, integration and end-to-end tests) to fail
before the code to implement the business logic checks is implemented but in this case the tests would never fail. I hope these are enough reasons to
point that this is definitely the wrong way to test such functionality in an asynchronous system.

An alternative, which i feel is too heavy and unnecessary expense for these sort of test is to modify your tests as such:

SendAPostRequestToCreateAnEntityComplyingWithBusinessRules()
QueryAndWaitForEntityToBePersisted()
SendAPostRequestToUpdateAnEntityNOTComplyingWithBusinessRules()
QueryAndWaitForUpdateEntityToNeverPersisted()

So i guess the question in your mind would be … What are you proposing?

As i have said in my previous post, your test coverage is a combination of tests written at the different layers of the testing triangle.
I would push this test to a lower level such as unit test for the appropriate layer in the architecture. This is an activity that needs to be carried out in
conjunction with developers and being able to make a compelling case should get you the necessary support to write such unit and/or integration tests.

Posted in Software Testing | Tagged , , | Leave a comment

Testing an Asynchronous System

In recent months i have been testing a system built using the CQRS pattern. CQRS stands for Command
Query Responsibility Segregation and you can read more about it here.

As a tester, one of the key takeaway for me is that there is a Read side and a Write side to the
application. This is very different to the other applications that i have tested in the past where a write operation would NOT be successfully until the data being sent to the application is successfully persisted.

In the case of this system that has been built using an event driven architecture, the write side of the application would always come back with a successful response which implies that the command is successful (provided that the api contracts and json schema validations are met) and this doesn’t mean that the data has been persisted. This is due to a concept referred to as eventual consistency.

Without going into the technical details, the internals of the system is event based, which means that every actions triggers one or more events which are picked up by other parts of the system and eventually the data is persisted; provided all the business rules and validation conditions are met.

So this poses a challenge as to how best to test this system and in my opinion this forces technical testers to look beyond writing API test and seeks cheaper ways of testing the system i.e Traversing the entire testing triangle pushing tests to integration tests and unit tests.
See my previous post here where i have spent a lot of time discussing how testers should consider the true costs of testing.

For an asynchronous system, there is an incredible amount of polling that has to take place in end-to-end tests that involve the full stack.
Also, testers have to understand the dependency between different actions that could be happening around the same time, so our tests would look like below:

doAction1()
waitForAction1ToBePersisted()
doAction2()
waitForAction2ToBePersisted()
.
.
.
.
doActionN()
waitForActionNToBePersisted()

I have always considered end-to-end test to be very expensive but the nature of this system adds more complexity to our tests and tests would take an awful long time to complete; hence it is more important that we reconsider how and where we test our system.

Posted in Software Testing | Tagged , , , | 1 Comment

Geb and Spock: My favourites for test automation

So I have used quite a number of tools in my time building test automation frameworks over the years; and in the last 2years i have evaluated a number of these tools and i am becoming more and more opinionated in my choice of tools.

For someone that has used selenium/webdriver and cucumber a lot in the past, i find myself using Geb and Spock these days and it hasnt been much difficulty in switch to these tools.

Geb has won my heart with the syntax and for people that have used it before it is uses webdriver under the cover and you can drop down to the layer below it; if you choose to use webdriver directly. In the time i have used Geb, there are times i’ve had to do this but i love the DSL which Geb provides and i hate when i have to use webdriver directly.

I love cucumber, and i know that the regex matching between step files and step definition files is quite powerful; however i find that the manner in which spock eliminates the need for a seperate text file  cool. Also with a very big test suite, i have that the Regex could introduce a maintenance overhead, hence the reason i prefer to use Spock.

However, I didn’t like the default report that comes with spock and i decided to include a library called ‘spock-report‘ which provides better reporting that one bundled with spock.

I have created an example project and it might be a good start for anyone wanting to look at this ..

 

Posted in Agile Delivery, Software Testing | Tagged , , , , , | Leave a comment

Never too early to start thinking about your tests

This post is spurned by taking a reflection on my journey as a tester and it’s amazing to see how much i have moved from designing large UI test suites to very small UI test suites. For emphasis, the largest test suite had taken over 8 hrs and the smallest has been 3mins of execution time.
There are a lot of posts on the internet about how fragile a UI test framework could be and i would expect the next question to be how have you been able to achieve this. I would try to address this in this post.

1. Thinking about tests while designing the system: There are some decisions made in the early stages of the projects that has a direct impact on how easy or how difficult It would be to test a system. E.g. a web application that has been built with RESTful api and with minimal business logic embedded within the UI lend itself to proper layering of test automation when compared to a system with loads of logic embedded in the UI logic.

2. Testing is done at the cheapest level:
There is always a cost associated with test automation, cost in terms of test creation, test maintenance and test execution. As testers and developers we ought to think about the cost we incur and determine at what level the tests should be written.

Test Creation: The project test suite should be split between unit test, integration tests and end-to-end tests. The end to end tests can be further split into two categories, api tests and user interface tests. The cost associated with test creations would generally increase as we move up from lower levels of test automation to more abstract levels such as User interface tests. However, in some instances e.g. rewrite of legacy applications without any form of test automation, it might be easier to create a quick UI test suite using record and play tools. There isn’t any rule of the thumb on this but I would advise the team to have this conversation at all times discussing how to best automate tests for new features and updates to existing features.

Test Maintenance: This is the cost associated with updating tests as the system continues to evolve, and in my experience its generally cheaper to update lower levels of test automation and this can be done in parallel with development of features.

Test Execution: This can best be expressed in amount of time it takes for a test suite to run from start to finish, and I would like to include the time elapsed when the tester and/or developer is waiting for the test result. It also makes sense to include efforts involved in interpreting the any test results including test failures. Bearing in mind that the automated test suite is expected to be executed several times in a day, over the life time of the project this is one aspect that could potential be the most expensive. The teams test strategy should ensure that the lower level tests which are generally faster needs to contain the majority of the tests I.e. unit, integration, api tests.

3. Collaboration with developers: No matter how solid a test automation strategy is, it would never be complete if there hasn’t been any thoughts about how to collaborate with developers. It is very common to have the unit tests and integration test be designed and maintained by developers while testers would design and maintain the end-to-end test suite. The consequences of such practices include test duplication and test omission. At the end of the day we should all be working as a team, testers should take interest in Unit tests and integration tests; ensuring that these tests are relevant at the least and we should be able to suggest scenarios to be added to the test suite even if we do not have the skills to write such on our own.
On the other end, developers need to be involved with design and maintenance of end to end tests, developers should be able to advice testers if a proposed end to end test (usually expensive) can be written cheaply in a unit test and/or integration test.

These are some of the ideas that have helped me with achieving a lean UI test automation suite and i do hope you find this useful as well.

Posted in Agile Delivery, Test Strategy | Tagged , , , , , | 2 Comments

Copying objects between two different amazon s3 accounts

I have recently taken on ownership of a website and as part of the migration task i’ve had to copy over a few artefacts;I will be posting another blog about what i have learnt from this process.

The website uses Amazon s3 for storing users’ uploaded photos and document. I was faced with the task of copying these files over to my S3 account.

Quite a number of way to achieve this; but i stumbled on a link which is a python script that copies object between two buckets in the same account.

I have then updated this script to handle copying objects between two different accounts.

The edited script is as below:

from boto.s3.connection import S3Connection
from boto.s3.key import Key
from Queue import LifoQueue
import threading

source_aws_key = '*******************'
source_aws_secret_key = '*******************'
dest_aws_key = '*******************'
dest_aws_secret_key = '*******************'
srcBucketName = '*******************'
dstBucketName = '*******************'

class Worker(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.source_conn = S3Connection(source_aws_key, source_aws_secret_key)
        self.dest_conn = S3Connection(dest_aws_key, dest_aws_secret_key)
        self.srcBucket = self.source_conn.get_bucket(srcBucketName)
        self.dstBucket = self.dest_conn.get_bucket(dstBucketName)
        self.queue = queue

    def run(self):
        while True:
            key_name = self.queue.get()
            k = Key(self.srcBucket, key_name)
            dist_key = Key(self.dstBucket, k.key)
            if not dist_key.exists() or k.etag != dist_key.etag:
                print 'copy: ' + k.key
                self.dstBucket.copy_key(k.key, srcBucketName, k.key, storage_class=k.storage_class)
            else:
                print 'exists and etag matches: ' + k.key

            self.queue.task_done()

def copyBucket(maxKeys = 1000):
    print 'start'
	
    s_conn = S3Connection(source_aws_key, source_aws_secret_key)
    srcBucket = s_conn.get_bucket(srcBucketName)

    resultMarker = ''
    q = LifoQueue(maxsize=5000)

    for i in range(10):
        print 'adding worker'
        t = Worker(q)
        t.daemon = True
        t.start()

    while True:
        print 'fetch next 1000, backlog currently at %i' % q.qsize()
        keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker)
        for k in keys:
            q.put(k.key)
        if len(keys) < maxKeys:
            print 'Done'
            break
        resultMarker = keys[maxKeys - 1].key

    q.join()
    print 'done'

if __name__ == "__main__":
    copyBucket()

Pre-requisites are you have to install python and install the boto s3 library.

and obviously you have to put your credentials in there

Posted in Programming | Tagged , , | 2 Comments

Assign AutomationIds to DevExpress ComboxBoxEdit Control

For some time i have been trying to automate a desktop application which uses a lot of DevExpress controls. For someone coming from a web application environment; this was  a very difficult task for me as i had no experience of WPF or any of the other custom controls framework out there.

So that i dont have to repeat myself i would post a link to the post i put on the devexpress website but i hope to flesh out a detail blog post sometime in the future so that other people can learn from me.

http://www.devexpress.com/Support/Center/Question/Details/Q452914/focus-answer-ee71c273-5f00-11e2-bf12-f0bf97cd2df9

 

Posted in Software Testing | Tagged , , | Leave a comment