An example and boilerplate for Automation Framework based on Ruby (not RoR). In mostly cases I'll be using this skeleton for building automation on Ruby...
An example shows a partial testing of todoist.com application. There are two specs implemented to display posibilities:
- integration - a small testing that covers CRUD tasks on 'Today' page, also can be mentioned as e2e test (simplification is made due to absent knowledge of projects info)
- system API - a test for /user/register endpoint (happy path excluded) represents posibilities of API testing
- Ruby - latest version of Ruby used as a programming language base.
- RSpec - unit tests framework used as a tests runner.
- Watir - Selenium wrapper which gives cross-browser and elements access simplification.
- Airborne - library for simplification API testing, gives simplification to making requests and additional RSpec matchers for testing responces.
- Faker - a library that generates unique predefined testdata.
- Logging - a library that provides an extended log outputting that can be mastered to STDOUT, file, or external integrations.
- DotEnv - a library that manages configutation for whole framework, it provides system Environment Variables into a framework and simplifies management on CI.
Implementation stored in ./tools/page_object_model.rb file.
It contains BasePage
class, which holds basic needed methods and implementations. Extended classes may be dealing with @browser
for accesing selenium elements. Details on Watir website.
For holding additional parameters for page there is an @additional
object, For example @additional[:url]
could be used to store an addition to base url for opening specific page via #open
method.
PageObject implementation should be a class:
- stored in
./pages/**/*.rb
file - extended from
BasePage
- implement private methods as selectors
- implement public methods as actions
Also self.printout self.public_instance_methods false
at the end of the class implementation will automatically do a printout to log output for all public methods (actions) within the POM class.
There is also kind a ClassFactory
implementation for RSpec which allows to use method on
instead of holding class instances for POM. There are 2 usages of it:
on(PageClass).action
- for single or chained actionson PageClass { |page| page.action }
- blocked for multiple actions
I prefer testdata to be automatically generated, this gives an extra multiplication to the executions and some random for coverage.
Simple single string data is generated via Faker
gem, it's automatically synchronized with RSpec seed. You can reproduce data with providing seed in ./specs/spec_helper.rb
(password may still be unique and not repeated). Whole implementation in stored in ./tools/datagen.rb
Also it implements entities which is a stored testdata objects integrated with a product. So DataGen allows to produce testdata through the API, use them for tests and cleanup at the end of execution.
Entity is a Hash extended class that produces an API posibilities:
- stored in
./entities/[type].rb
- class named
[Type]Entity
and extended fromEntity
class - may use
Airborne
andFaker
for implementing posibilities - must implement
#cleanup
method (for post-conditions cleanup)
DataGen
itself can be used within the tests, and implements:
#new
will generate NEW item for entity (use separate method to save it to product)#use
will return last generated entity, to use it within further actions in test#mark(type, context, entity)
- will mark for post-execution cleanup where: - type is a symbol name of entity:type
, - context is one of :test, :suite which means it will be cleaned up after test or suite respectively, - entity is a specific entity or latest created for type is not specified.
This framework is working upon logging gem. That's why there is deprecated puts
method, and logger.[level] might be used instead. Whole logger is being implemented as monkey-patching Kernel module and stored in ./tools/logger.rb
debug
method allows to inspect internal data during execution. It allows to use multiple variables via comma.
logger.[level]
outputs a message on specific level message. By default gem implements folloding levels, and they are used for proper messages respectively:
api_d
- API Data, requests and responses detailsapi
- API, generic info for requests and responsespom
- PageObjectModel, actions executeddebug
- Debug, custom messagesdata
- TestData, entities posibilities executionsrunner
- Runner, RSpec config and examples data and statuseswarn
- Warning, something that may affect tests executionerror
- Error, failure that will definitelly fail further execution
sleep(duration, reason)
wrapps generic Kernel method. There is a meaning that using sleeps is a bad practice. For now it will produce a warning message for sleeps without a reasons. The best case is to use @browser.wait_until
instead of sleeping.
breakpoint
can be used for development and debugging the tests. It's being maintained via AVOID_BREAKPOINTS
env variable. It's being set to true
on CI which will produce an error output instead of stopping execution.
Framework is being implemented and used within *unix system. Defaulty it's managed to be working under debian(Ubuntu) and rhel(Fedora) systems, but can be runned everywhere where Ruby is working.
Supported and tested OSes:
- Ubuntu
For supported systems there is a script which automatically installs all requirements. Just call ./install.sh
(it will install rvm and use it for execution)
On other systems install latest version of Ruby(+gem), then install Bundler via gem install bundler
(maybe with sudo
), and then do bundle install
For supported systems: ./run.sh
, then can be used arguments like --tag
or path for spec files.
Others just use bundle exec rspec
with needed arguments.
Execution produces detailed STDOUT with specific format.
Also due to connected junit formatter execution produces an XML file to ./results/
directory
Additionally each failed UI example produce a screenshot to ./results/screenshots/
directory
- ./entities/**/*.rb - DataGen testdata entities classes.
- ./pages/**/*.rb - POM PageObjects classes.
- ./results/ - a folder with execution results.
- ./spec/**/*_spec.rb - a folder with tests itselves.
- ./spec/spec_helper.rb - a helper file which stores generic RSpec config which requires to each test file.
- ./tools/ - a directory for wrappers and helpers used within framework.
- ./tools/api_wrapper.rb - Patch for Airborne gem which porduces proper output.
- ./tools/configuration_parser.rb - DotEnv implementation.
- ./tools/datagen.rb - implementation of DataGen, described earlier.
- ./tools/logger.rb - Kernel monkey-patch for implementing Logging gem.
- ./tools/output_formatter.rb - an RSpec Formatter which implements custom output for examples execution to Logging.
- ./tools/page_object_model.rb - an implementation of
BasePage
andClassFactory
for POM. - .gitignore - generic ignoring for git.
- .ci.env - default config for CI
- Gemfile - a file with gem dependencies
- install.sh - framework installation script
- README.md - this file
- run.sh - framework running script