In the following series of posts we gonna create todo list app in rails. In this tutorial we’ll create basic structure of our app. In first part of tutorial you will learn:
- How to install Rails
- How to choose text editor for your operating system
- How to use Rails in command line
- How to use Bundler to install gems
- How to use Cucumber with Capybara to test our pages
- How to create our static_pages(home,about,contact)
1 What do you need
You need to have some basic knowledge of HTML, CSS. If you haven’t learn them yet go to web tutorial on codecademy
You need to have basics in Ruby. If you haven’t I wrote post about learning resources for ruby
You need to have ruby and ruby on rails installed. I will explain this in next section
2 How to install Ruby
In this post I’ve included installation instructions for Ruby and Rails
3 Choosing your text editor
You write all your ruby programs using text editor.
For Windows I recommend you this editor. It’s free and it includes syntax highlighting and auto completion for ruby.
On Mac you can use TextMate. You can download it and install for free.
On Linux you can use gedit.
4 Creating basic structure of the app
Ok so you’ve got your tools in order, so we can start to create application. Open up terminal window or command prompt if you’re on Windows and enter following code:
$ rails new todo --skip-test-unit
This will create rails application named todo. It takes a while. Ok let’s check out some folders that we’re created.
That’s the file that you will use to install all dependencies what you need for your applications. They’re called gems. Just add name of gem to your Gemfile and let Bundler to take care of installation.
In this folder you place your html templates.
4.1 How to use Bundler
After creating rails application you should use Bundler to use all dependencies what you need. First add name of the gem to your Gemfile, then open up terminal and add following command:
$ bundle install
Let’s add some gems to your Gemfile. Open up your Gemfile and add following gems:
gem 'slim-rails' gem 'capybara' gem 'cucumber-rails', :require => false gem 'database_cleaner' gem 'rspec-expectations' gem 'selenium-webdriver'
Install it with Bundler:
$ bundle install
4.2 Starting our application
To run your application, type this into command line:
$ rails server
Go to web browser and type localhost:3000. Your output screen should look like this:
5 Creating Static Pages
We have our web server running let’s build some pages.
5.1 Creating controllers
$ rails generate controller StaticPages home help about --no-test-framework
If you open your views folder, you should see that you have new folder named static_pages with some files in it. Go to the config/routes.rb, you should see path of our pages that we’re created. Type for example, localhost:3000/static_pages into your web browser.
We created StaticPages controller and we can populate our files. Testing every change in a browser would be tedious. So we gonna need Cucumber and Capybara to do it for us.
Cucumber lets software developers and shareholders to use simple plain language to describe features. If you want to know more about Cucumber, try CucumberBook #### How Cucumber works
Cucumber works in features which are written in plain text and step definitions which are written in regular ruby code. If you go to your app folder, you should see that folder named features was created.
First we need to setup folder structure of Cucumber. Run following command:
$ rails generate cucumber:install
We need to test all our static pages. Open up folder features in your main directory and add file static_pages.feature into your features directory.
Feature: Static Pages content User should see static pages content Scenario Outline: Path testing When I visit <Path> path Then I should see following content: <Content> Examples: | Path | Content | | Home | Todo | | About | About | | Help | Help |
This is how it works. At first line you define your feature, in our example StaticPages content. Then you define your steps. Steps always begin with keywords: Given,When,Then,And and continue with regular expression. It can be any text. Don’t forget to surround your text in regular expression like this: /^some text$/
We have our feature defined, let’s test it with Cucumber
You should see something like this:
Ok we’ve saw undefined scenarios and steps let’s actually implement it. Open up folder step-definitions and create file static_pages_steps.rb
When /^I visit Home path$/ do visit 'static_pages/home' end
In first line we match name of our step with name in the feature file. Then we use capybara to visit home path in the browser. Run your test with cucumber. You should see one passing test.
Now we need to test content of our home page. Add this into features/step_definitions/static_pages_steps.rb:
Then /^I should see following content: Todo$/ do expect(page).to have_content("Todo") end
In first line we match second step with feature file. On the second line we use Rspec Expectations to test content of our home page.
Run cucumber again. You should see failing tests. Of course that test is falling, we don’t have content Todo in our templates.
Open up folder app/views/static_pages and edit file named home.html.slim.
5.3 Why to use Slim
Maybe you wonder why we’re using files with slim ending. Slim is a template language that strips all unnecessary elements as opening and closing tags. For example this is a code in html:
<html> <head> <title>My WebPage</title> </head> <body> <h1>My heading</h1> <p>My paragraph</p> </body> </html>
And this is code in Slim:
html head title My WebPage body h1 My heading p My paragraph
You see that Slim code is shorter and easier to read as Html code. Let’s return to our file. Replace content of home.html.slim with following content:
You should see that our test is now passing. Implement this to remaining steps in our feature file.
When /^I visit About path$/ do visit 'static_pages/about' end Then /^I should see following content: About$/ do expect(page).to have_content("About") end When /^I visit Help path$/ do visit 'static_pages/help' end Then /^I should see following content: Help$/ do expect(page).to have_content("Help") end
All our tests are now passing, next step will be implement title tests. Open up your static_pages.feature file and append following line:
And I should see following title: <Title> Examples: | Path | Content | **Title |** | Home | Todo | **Todo |** | About | About | **About |** | Help | Help | **Help |**
Let’s implement our test. Add these lines to our steps file.
And /^I should see following title: Todo$/ do expect(page).to have_title("Todo") end And /^I should see following title: About$/ do expect(page).to have_title("About") end And /^I should see following title: Help$/ do expect(page).to have_title("Help") end
Let’s fix failing tests. We need to change our title in our templates.
html head title Todo
html head title About
html head title Help
Let’s run cucumber again. You should see that’s all our steps are now passing. We are done.
6 What to improve
6.1 Watching step changes with Guard
There’s lot a place to improve. For example running cucumber every time for every change in terminal it’s disgusting. Let’s change it. We can use Guard to watch every change in our features folder. Add Guard to your Gemfile.
And install it:
$ bundle install
Let’s add Guard to Cucumber.
$ guard init cucumber
If you open your app’s folder you should see that file named Guardfile was created.
Let’s run Guard to run our features automatically.
All features are running automatically by now.
6.2 Eliminate duplication in title
Take a look at files in views folder. You saw that we’ve writed title tag three times. That’s terrible, let’s do something about that. First rename file in app/views/layouts directory.
mv application.html.erb application.html.slim
Delete all content and replace it with following:
- provide(:title, 'About') h1 About
- provide(:title, 'Help') h1 Help
6.3 Linking our pages and updating routes
Typing long adresses like static_pages/home is very disgusting, if we instead use shorter address, it wouldbe much better.
Open up config/routes.rb and replace it content with following:
root "static_pages#home" match "/help", to: "static_pages#help", via: 'get' match "/about", to: "static_pages#about", via: 'get'
And change tests in features/step_definitions/static_pages_steps.rb like this:
When /^I visit Home path$/ do visit '/' end When /^I visit About path$/ do visit '/about' end When /^I visit Help path$/ do visit '/help' end
Let’s take a look at code we’ve just wrote.
This code creates root path for our pages. In this time it’s static_pages#home. So you don’t have to write your path to web browser. Start rails server. You should something like this:
That’s good but your visitors don’t have time to write short path like /help to your webrowser. You haveto include links on your root page.
Add this code for adding links to your app/views/static_pages/layouts/application.html file after the body tag.
nav ul li = link_to "Home", root_path li = link_to "Help", help_path li = link_to "About", about_path
You should see links on your home page.
We’re done here. In next tutorial we’ll do some styling to our app