In previous posts regarding the Lucid tool, I showed how to use it in terms of its basic execution cycle as well as how to augment that cycle by calling out to an external library. In this post I’ll show how Lucid can help people get started with the tool by having it generate a particular project structure for you.
[ UPDATE: As of LucidGen 2.0.0, released on 5 May 2014, the project no longer supports the Fluent library by default. Instead it now supports the much slimmer Symbiont library. Upcoming blog posts are going to talk about this updated aspect of the framework. In the meantime, if you are following these posts you can still get the 1.0.0 version of the LucidGen gem, which allows you to use the Fluent gem as documented here and in following posts. Simply do this: gem install lucid-gen -v 1.0.0. ]
[ UPDATE: As of Lucid 0.4.0, released on 15 February 2014, the project generator has been separated from the Lucid project. The generator is now available as a separate gem called lucid-gen, available at LucidGen. I should also note that the files generated are slightly different: the contents of browser.rb and events.rb are now placed in the driver.rb file. Thus browser.rb and events.rb are no longer generated. ]
When you install the Lucid gem you end up with the equivalent of an executable called ‘lucid’. This is what you use to start the actual Lucid execution cycle, which means finding test specifications and using the test definitions to execute those specs. You also get an executable called ‘lucid-gen’ and this refers to a “lucid generator.” What this will help you do is generate certain types of project structures.
Using the Project Generator
If you went through any of the previous posts on Lucid, you know that the first thing you need to do is make a directory where you can store your repository of test specification files. As you’ve seen, you can simply create a directory of your own and start working right away. You’ve also seen that Lucid will automatically look for certain directories and process the files that are in them.
What the project generator does is create a directory structure for you based on some conventions as to what an effective directory structure can be. This is no more or less opinionated than what tools like Rails or Maven do as part of their operation. Try running the generator:
This will provide you with some built in help. You will see that currently about the only command you can run (besides help) is called ‘project’. Get some help on that command:
$ lucid-gen help project
The syntax for this is fairly simple: you call the ‘project’ command with a name. Note, however, that there is an option to specify a driver. This is the framework driver you want to use and you are told that it will default to something called ‘fluent’.
If you went through the post on using Lucid for testing web apps you’ll know that there I used a library called Capybara. Specifically, that was the driver I used for connecting up the test specifications with the implementation of a browser-based application. Fluent is just another such library, albeit it happens to be one that I wrote. Rather than cover lots of details about Fluent here, I’ll show how it can be used with Lucid.
First, let’s create a new project:
$ lucid-gen project tutorial-web
This will create a project directory called ‘tutorial-web’ for you and populate it with relevant files for the default project type.
You’ll notice how Lucid indicated it was creating a project called tutorial but also that it was “using fluent.” By default, the structure that is set up presumes that you are testing a web application and that you are using the Fluent test automation framework. What this should indicate to you, however, is that different project structures could be set up that could be generated by lucid-gen.
The Starter Directory Structure
tutorial ¦ Gemfile ¦ lucid.yml ¦ +---common ¦ +---config ¦ +---data ¦ +---helpers ¦ +---support ¦ browser.rb ¦ driver.rb ¦ errors.rb ¦ events.rb ¦ +---pages +---specs +---steps
Here are some basics about what has been generated:
- The specs directory will contain your test specifications, written in a TDL.
- The steps directory will contain test steps that include matchers for TDL statements.
- The pages directory will contain page definitions that represent web site pages.
- The common directory will contain elements common to all specifications.
Looking into the common directory, the directories here are largely just meant to guide your thinking. They can be changed to whatever you want or even removed entirely.
- The config directory is meant to hold environment configuration information.
- The data directory is meant to hold test data, including templates for test data.
- The helpers directory contains test helper functionality, such as supporting logic.
- The support directory contains logic that connects Lucid to a test automation system.
The operating idea is that any files that may need to be referenced by specs, steps, or pages will go in the common directory.
All of this is a convention-based directory structure to allow for an easy separation of concerns. However, none of this is set in stone. All of the directory names can be whatever you want and, in fact, you can make more or less directories depending on what you want. Technically, you could use Lucid by just having a single directory with all files — all specs, all code logic, all test data — placed inside it.
Of particular note is that any of these directories can have numerous sub-directories. Lucid will start reading at a top-level directory and will read all directories underneath that top-level as well. The reason for this is that Lucid is designed to work with certain conventions but is also designed to allow you to set configurations that will override those conventions.
It is important to note that the directories scanned for test definitions and any common code are determined by the spec files (or directories) you pass to Lucid. So, for example, if you specify a particular spec file like this:
$ lucid specs\my_spec_file.spec
Lucid is going to look in that specs directory for any files, including code files. Lucid will also look at any directories under the specs directory. Now let’s say you have numerous directories underneath specs and you choose to run anything under that directory:
$ lucid specs\my_specs_dir
This now means that Lucid will look under that ‘my_specs_dir’ directory only for any files.
So if you are not using the standard directories that Lucid will automatically look for — common, steps, pages — then Lucid will limit where it searches for code files.
You can always do this:
$ lucid --verbose
This will show you where Lucid is looking for code and will also show you what files it found and accepted as well as what files it found and rejected. Lucid will reject files if it does not recognize them and thus does not know how to use them as part of its execution.
The Starter Files
A few key files are used to make sure that automation against a browser can take place:
tutorial +---common ¦ +---support ¦ browser.rb ¦ driver.rb ¦ errors.rb ¦ events.rb
A rough breakdown of these provided files is as follows:
- The driver.rb file is a file that is read first no matter what other files exist. This is the file that starts the process of setting up the necessary environment or hooks into libraries.
- The browser.rb file is what provides a hook into the browser, including a browser driver.
- The events.rb file is what provides an event handler to allow for certain actions to take place when events occur, such as “before a scenario”, “after a test step” and so forth.
- The errors.rb file provides a series of specific error conditions that can be raised as part of execution.
Lucid can be configured via the command line. But Lucid can also operate with different operational profiles that indicate how you want Lucid to execute. When you create the default project, you will see a file called lucid.yml.
Lucid will not generate one of these files by default but here is an example of what one would look like:
<% browser = "BROWSER=firefox" %>
<% std_opts = "-r common -r pages -r steps" %>
<% rpt_opts = "--format html --out results/specs-report.html" %>
default: <%= browser %> <%= std_opts %>
report: <%= browser %> <%= std_opts %> <%= rpt_opts %>
You will see that there are two profiles: default and report. If Lucid finds a lucid.yml configuration file, and if that file contains a profile configuration called ‘default’, then Lucid will use that profile configuration. You can specify other configurations at the command line. For example, to run the ‘report’ profile configuration you would execute Lucid this way:
$ lucid -p report
If you don’t specify a profile argument at the command line but Lucid finds that do have a lucid.yml file, then Lucid will automatically pick the default configuration from the file.
You may also note that the lucid.yml file can contain string templates. The file created by default sets up string templates, in between <% and %> elements, called browser, std_opts, and rpt_opts. Those templates can then be re-used in the configuration file, by placing their name between <%= and %> elements.
As a final note, the lucid.yml file has to be placed in your project’s root directory or, as an alternative, it can be placed underneath a directory called config that would sit at the same level as your specs directory.
Getting the Necessary Dependencies
To continue, make sure you go into the project directory you just created:
$ cd tutorial-web
One of the files generated by the project generator was a Gemfile. This file contains all the dependencies that Lucid needs in order to execute. To get these dependencies in place, you can run the following:
$ bundle install
Note that this does require you to have the Bundler mechanism in place. If you are told that bundle is not a recognized command, simply install the gem:
$ gem install bundler
This will check for what gems you do and do not have available already. If gems are found to be missing, they will be installed.
Once you have the dependencies in place, now run the Lucid command:
You should get output like this:
Specs are being executed from: ["specs"] Using the default profile... 0 scenarios 0 steps 0m0.000s
If you get that, everything is running as it should be at this point. Clearly no execution of test specs took place for the obvious reason that there are no test specs yet. The Lucid project generator simply set up a structure with some operational elements in place, but writing test specs and test definitions is up to you.
This was a short post just to make sure you can use the project generator. In the next post I’ll talk more about what it means to use a library like Fluent with Lucid.