-
Notifications
You must be signed in to change notification settings - Fork 2
05.01 Cucumber & Doubles
Behaviour/Test Driven Design (Or B/TDD) is accomplished in this project by using the Cucumber gem combined with the Aruba gem and Aruba-Doubles gem. The format for cucumber scenarios: "Given", "When", "Then" is used repeatedly with doubles for the AWS CLI. Here is step by step example from "feature/elasticip/elasticip.feature"
First the scenario is expressed in terms of a user of the "zaws" application. Here "zaws" will allow a user to declare that an instance identified by the external id the user previously gave it should have an elasticip.
Scenario: Declare elasticip for an instance by external id
Next the interactions with AWS are doubled in the Given section of the test. This allows for the "zaws" utility to get precanned responses based on the specification for the JSON the AWS CLI would be expected to return given a known state of AWS resources. This first Given statement returns a portion of the JSON that would be returned when you describe the instances in ec2
Given I double `aws --output json --region us-west-1 ec2 describe-instances --filter 'Name=vpc-id,Values=my_vpc_id' 'Name=tag:externalid,Values=my_instance'` with stdout:
"""
{ "Reservations": [ { "Instances" : [ {"InstanceId": "i-abc1234","Tags": [ { "Value": "my_instance","Key": "externalid" } ] } ] } ] }
"""
Because the assigning of an elastic ip requires additional AWS CLI calls, those are also mocked out. After I have the id of the instance from the previous call, I need to describe the addresses to see if an elasticip is assigned already to the instance. And since it is not I need to then allocate the address, and finally associate the address. All these calls have the corresponding specified JSON returned as specified so that the code under test can be developed to interact with it.
And I double `aws --output json --region us-west-1 ec2 describe-addresses --filter 'Name=domain,Values=vpc' 'Name=instance-id,Values=i-abc1234'` with stdout:
"""
{ "Addresses": [ ] }
"""
And I double `aws --region us-west-1 ec2 allocate-address --domain vpc` with stdout:
"""
{ "PublicIp": "198.51.100.0", "Domain": "vpc", "AllocationId": "eipalloc-abcd1234", "AllocationId":"eipalloc-abcd1234" }
"""
And I double `aws --region us-west-1 ec2 associate-address --instance-id i-abc1234 --allocation-id eipalloc-abcd1234` with stdout:
"""
{ "return": "true" }
"""
Finally the portion of the command line usage of "zaws" that the user would actually run is specified as the "When" clause. With the expected return value immediately following.
When I run `bundle exec zaws elasticip declare my_instance --region us-west-1 --vpcid my_vpc_id --verbose`
Then the output should contain "New elastic ip associated to instance.\n"
Rspec testing is used for parts of the code that aren't specific to simulating user interaction. For example testing that a specific IP is in a CIDR so that the right subnet id of the associated subnet to a specific CIDR can be returned. The test prepares canned responses, sets expectations and then runs the code under test. If the expectations for the code under test are not satisfactory met then the tests fail. See file "spec/zaws/ec2/subnet/id_by_ip_spec.rb" for an example of this type of testing.