So you want to do integration testing for your application, good for you. If you have chosen MiniTest and it’s specing DSL MiniTest::Spec as your test framework here is an example how to setup the integration tests to run fairly fast. Integration tests are similar to Cucubmer features, if you have used that before. I just like this style better because Cucumber, IMO adds too much noise, but it serves you as application documentation. I will also user Capybara for the webpage testing.
Because we are using minitest-spec-rails gem, we don’t need to tinker with the config/application.rb and test settings, because ActiveSupport::TestCase is a subclass of MiniTest::Spec
First we will set up the gemfile, with the needed gems( I also use guard for my automated tests, but it’s worth writing another blog post, soon hopefully)
123456
group:development,:testdogem'minitest-spec-rails'gem'capybara_minitest_spec'# for capybara integration and spec matchersgem'capybara-webkit'# for headless javascript testsgem'turn'# for prettier test outputend
After that we need to set up out test/test_helper.rb to use Turn and capybara
1234567891011121314151617181920212223
require'rubygems'require'rails/test_help'require'minitest/autorun'require'capybara/rails'require'turn'classActionDispatch::IntegrationTestincludeRails.application.routes.url_helpers# for x_path and x_url helpersincludeCapybara::DSLincludePossibleJSDriver# switching Capybara driver for javascript tests, look belowend# switching to the javascript driver in integration testsmodulePossibleJSDriverdefrequire_jsCapybara.current_driver=:webkitenddefteardownsuperCapybara.current_driver=nilendend
After you have everything set up you can use all of this in your integration tests, here is an example of one integration test, without and with javascript browser turned on(require_js turns on the webkit driver)
1234567891011121314151617
require'test_helper'classLoginTest<ActionDispatch::IntegrationTestbefore{visitlogin_path}describe"signup text"doit"must have a signup text"dopage.must_have_content("Don't have an account?")endit"must have a signup link"dopage.find_link('Sign up').wont_be_nilendit"signup link must go to the signup path"dorequire_js# this one turns on the webkit javascript driverclick_link('Sign up')current_path.must_equal(signup_path)endendend
I have tested the integration test speed with :webkit as a default capybara driver and it runs at the same speed as the normal :rack_test driver, so you can go that way too.
Toptal is a relatively new company, similar in many ways to other freelancing sites available, but it has a twist.
I received an email from a recruiter last month and after a few hours inspecting the site,
and watching the CEO’s talk at the Harvard Business School
http://youtu.be/Ffjx_hl3IE8 i decided to contact them.
I first had a nice chat with the recruiter explaining in depth what the company does and what can
be our mutual benefits if i continue to pursue the arrangement. Later that day i was contacted by the CTO
and scheduled a skype call with him. The skype call was a first test, Toptal
cares that all developers are very fluent in English, not only written, but also in spoken form.
The interview was no stress at all, a standard chat between two engineers that just met.
After that i received the next test, solving some automated tests.
The tests weren’t really complicated but the time is limited to 45 minutes, i could write about the perils of automated testing,
but that isn’t the case there, it’s just one of the screens. Interview number 3 was a pair programming session where another
developer joined my shared screen session and gave me assignments, also solving some algorithms, but with him watching me writing code.
After i passed that test, there was another, to create an AJAX web application with REST API and authentication.
I did my best on a limited schedule and passed that test too and became a member of a growing number of their network of senior freelance developers.
To save you the trouble, i’ll write something about Toptal and why they are not the same as Elance, Odesk or other freelance sites.
Toptal hires freelance engineers, then tests them, and has people
working with them and the clients to find the best match for the engineer and the client.
That way you already get tested and able engineers to work with them.
Also the engineer is instructed in detail about the job he is interviewing for and can prepare for it.
All of the recruiters are engineers so it makes the stuff easier because everyone understands the problems.
You as a client, have the possibility to try out a few developers until you find one that suits you and can hire them either part or full time whatever suits you.
The bottom message is: If you are in need of top talent to develop you application or you are a skilled developer who wants to work for some of the best companies in the world join Toptal and give us a try.
So, you want to develop your big Point Of Sale(POS) solution on android but don’t know how to print the receipts. You have a few options:
Make a centralized mobile web application, reachable on wifi and use your tablets to take orders and print the receipts at the bar.
Use some kind of a Windows Mobile/CE handheld device with a printer
Make an Android app and print via Bluetooth
Due to the requirements of the project i have been working on, i have made a solution somewhere between 1 and 3, using Ruby on Rails for back end administration and api, and using Android tablets for billing. As for the printing of the receipts, the only POS printer we could find on our market with Bluetooth capabilities was Bixolon SPP-R200 so i decided to use it. And the Bixolon support guy Jörg from Germany was really helpful, and sent me the android api so all i had to do was include one jar file and write a class for handling the printer. You also get the whole example application, with every api call available.
For my needs, and future compatibility, i first integrated everything into the activity, yes silly of me, but then i extracted it into a class and also created a printing interface which my app now uses, and it can be used across multiple apps very easily. First a basic printing interface:
All that is remaining in your activity is to declare a variable of the Printer type and instantiate a new BixolonPrinter class.
12345678910
publicclassTestActivityextendsActivity{Printerprinter;@OverridepublicvoidonCreate(BundlesavedInstanceState){// TODO: implement this into settings and choose based on thatprinter=newBixolonPrinter();printer.connectPrinter();}}
I chose this path because one company that is in mobile solutions in Croatia heard a presentation about the application, and decided to lend us a Zebra mobile POS printer(don’t really know which model), to implement it into the app. I will publish the implementation here as soon as i can.
You can get the Bixolon api and documents by registering to the bixolon
developer’s site Bixolon developer site
If you are considering about using some kind of pagination like will_paginate or some pagination of your own flavor, and you are stuck using Oracle i have a solution for you. Oracle is known not to have limit and offset helpers for the select statements. Those two pieces of code that are missing are helping us to paginate properly. Yeas, you can use rownum, and i am using it too, but we have to encapsulate our select a few times, so it won’t make trouble for us(bad data, not ordering properly or something).
I have already made a patch for arel, so it’s embedded in Rails, if you really have use Oracle as your database.
Let’s say that we want to list all the employees from scott.emp table, and order them by empno descending and fetch the records from rows of that data 41 to 50.
We are all excited in a new addition to rails plugins family that is turbolinks.
If you have tried to include it in your application, you may have noticed that turbolinks doesn’t trigger your $.ready, because there is no full page reload. As a consequence your javascripts that are bound to $.ready won’t trigger. I will only hack the finished event that is “page:change” which occurs when the page is refreshed. You have other events and their descriptions on the turbolinks github page. Here is a fast hack that i came with. Some of the code is taken from turbolinks library.
First have your $.ready trigger the “page:change” event. This is done, so we can bind everything that is now bound to document.ready to “page:change”
Have you ever wondered why is there no remote option for will_paginate gem? It’s too complex and data dependent to handle all possible situations. I have made a workaround that can help you implement simple ajax pagination for your rails application. I will be replacing the whole yield part here, but you can customize it whatever way you like.
Extract your required view into a partial so you have
We also change the address in the navigation bar with PushState, because it can happen someone will press F5 or something and reload with a different params[:page].
Update: As my coworker Oliver mentioned, i forgot to include responding to js in our controller for the index action
We have a new product ready and it is a Ruby on Rails webshop bundled with an ERP software written on Oracle Forms 6i. I will not go into the details of this work, maybe later i will make some posts of the process but as it is very linked to current software(only authentication is done with Devise, every other data and processing is done internally on Oracle database) there is no sense for me to explain it deeper. Off to the installation.
Server installation and configuration
First we need a clean install of Ubuntu server 12.04, x86 or x64 version will work all the same, but be careful later on when you download the Oracle instant client. On the installation, fill all the relevant data needed, and for installed services, choose only the ssh server, as you won’t be needing anything more. Another reminder: this will only be the webserver, assuming that you have the Oracle database installed somewhere in network reach.
After you login to your server for the first time, take your time to set up the ip address because it defaults to dhcp.
Edit the /etc/network/interfaces file and fill your address, gateway and dns servers(this is a new thing, i think starting in 12.04 /etc/resolv.conf gets updated whenever you restart networking, so everything you write there will get overwritten)
/etc/network/interfaces
1234567891011
# The loopback network interfaceauto lo
iface lo inet loopback
# The primary network interfaceauto eth0
iface eth0 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 8.8.8.8 8.8.4.4.
After the config is saved, restart the networking and do a full update/upgrade of the server to get the latest packages installed:
After your server is updated you can proceed with installing RVM and the latest stable Ruby(as i’m writing this, the latest version is 1.9.3p194 so i will be using this version)
First we install RVM prerequisites:
12345678
# rvm requires curl and git to install, and you will probably need them on your server so go ahead and install themapt-get -y install git-core curl
# Installing RVM as sudo, to get RVM ruby system widecurl -L get.rvm.io | sudo bash -s stable
# sourcing rvm environment so you can use it untill you login againsource /etc/profile.d/rvm.sh
And that will install RVM and make it available for all users that belong to the rvm group(hint: edit /etc/groups and add rvm after the desired username). After installing RVM and adding our user to the rvm group we are off to installing latest Ruby version
1234567891011121314
# install all requirements needed for YARV/MRI Ruby (you can easily get these by running 'rvm requirements' in the terminal)sudo apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion
# install requirements needed for Oracle Instant clientsudo apt-get install libaio1
# install latest stable 1.9.3 and set it as default ruby versionrvmsudo rvm install 1.9.3 --default
# disable installation of RDoc and RI when installing gemsecho'gem: --no-ri --no-rdoc' >> ~/.gemrc
# install bundler gem, as you will later need for deploymentrvmsudo gem install bundler
Installing Passenger and Nginx web server
After you have ruby and everything needed installer go and install passenger gem and nginx web server with it
123456
# install passenger gemrvmsudo gem install passenger
# install passenger nginx module (and nginx if you haven't installed it yet), choose first option(Yes: download, compile and install Nginx for me) when it asks you what to do# if there are more requirements the script will tell you and after you install them rerun the commandrvmsudo passenger-install-nginx-module
The installation will set up the nginx.conf file for you and show you how you can enable a rails site on your server. But i will include a sample config later on.
Just for convenience, symlink nginx conf folder that is in /opt/nginx/conf to /etc/nginx and download linode nginx startup/shutdown script
To connect your Rails application to Oracle database, you will have to install Oracle client, either full or instant one. As installing full client requires alien and converting .rpm packages to .deb it’s a bit of a hassle. Also, it will consume more space on your drive, and all that is unnecessary, we are trying to keep it small here.
First you should download zip files from Oracle site depending what architecture you are running:
Oracle Instant Client 11.2 for linux: X86, X64
Download only instantclient-basic, instantclient-sqlplus and instantclient-sdk zip archives and unzip them all into the same instantclient_12_2 _ folder. Now as sudo move that folder so the path is /opt/oracle/instantclient_11_2 _
After that you only have to add two environment variables to be able to install ruby-oci8 gem, which is prerequisite for running Ruby applications on Oracle database. Add the following lines to /etc/enviroment file
1234
LD_LIBRARY_PATH=/opt/oracle/instantclient_11_2
# as i am from Croatia, and we use our national date and money preferences, my NLS_LANG is this one, yours will maybe be differentNLS_LANG=CROATIAN_CROATIA.AL32UTF8
After you reboot you have to symlink the oracle library so it will function properly(i don’t know why they don’t do this themselves).
If there are no errors, and there should not be if you followed the guide, you are set to deploy your application on the server you just installed. In the next post, i plan to write something about tips, tricks and caveats of developing Rails applications on Oracle database.
Useful links to get and learn about all the stuff i have mentioned in the post:
If you are a software developer like me, every once in awhile comes the opportunity to install your new development machine. Some of the causes can be a new job, new computer or just reinstalling your current computer.
I am trying to emphasize the importance of installing your own machine, just like Jedi knights have to build their own lightsabers, you should be competent enough to install the required software on your development machine.
I will try not to go into platform specific rants or anything, just a guideline on how to do it.
Know your OS - be it windows, linux or osx, please be familiar with the os you are planning to develop on, if you get stuck, search for some tutorials on the web. You should be very friendly with the command line, if you are planning to use linux, and even in some cases osx.
Know your platform - be it ruby, java, python, .net or anything else, learn how to install the basic tools to get you running, you have great video tutorials for just about anything, so go ahead and watch them.
Don’t be afraid to ask someone - take this one with caution, it is ok to ask for an advice, or if you get stuck, but never ask another developer to install some of the tools for you, as you then seem incompetent in their eyes.
And do try to follow some of the people creating the technology you are using on social networks, you can see some tips and tricks, update and version release announcements and everything else. Looking at a few cat pictures is sure worth it considering the knowledge you are getting from these people.
Due to some legacy issues, and HP workstations being shit that you can’t turn the hardware virtualization on, i had an issue with one client regarding speed and loading time of an application. My common deployment server is running Ubuntu on VMWare or Oracle VBox, passenger + nginx, or apache even. But, this “server” is just a regular machine(people here don’t want to invest in real hardware, or just don’t have the money).
So i had to deploy the app on windows 7, and i will show you how.
First, there are few steps you have to take care of:
Install Ruby DevKit from the same source(this will be needed for you to compile some native binaries)
Install Thin server(gem install thin)
Set up dropbox deployment for your application(i know this is monkeypatching as hell, but if it works…) as described on Rob Conery’s blog
Test the app and make sure everything is working ok, (run rails server), then thin start -e production, just to make sure everything is ok, and all of your gems work on windows(fix or replace the ones that don’t)
Set up the task scheduler(this is a fine piece of software on Win 7 and up) as described here, to run rails application almost as a windows service( you start with ‘thin start -e production -p 80 -c “path_to_your_app” ‘)
Write a nifty batch script that will restart the server, run migrations, compile the assets and whatnot.
After you pull to your dropbox synced repository, login to the server and execute the batch file from there to almost automate the deployment process.
I know this is not capistrano, and cap deploy, and it is hacked as it can be, and also, it works, it’s a small client so i don’t expect much trouble with this.
Lesson here: Try as much as you can to deploy your rails server on a linux server, best in a virtual machine. But if HP messes with you and you have some shitty hardware running windows, this is the best way i have found. If anyone has anything better, put it into comments, i’m happy to make my life easier.
I have encountered a problem with users on a webapp that i co-created. The users would click back after entering data in a form, or close the current tab or something. They were so used to client-server workflow, with open connections to the database that prevented that kind of actions. So i got handed the assignment to prevent the users from doing almost anything but submitting on a data entry form without a notice.
It seemed as a hell of a solution, but i managed to make a simple plugin that works on all major browsers, except Opera. Using window.onbeforeunload, we can prevent the user from doing anything that would hurt their unsaved data. you just load the javascript file, put a tag into your forms that you want to protect and it works out of the box with JQuery.
12345678910111213141516
varisSubmitted=false;window.onbeforeunload=function(){varmessage="You could have unsaved changes!";if($('form[data-validate-exit="true"]').length>0){if(!isSubmitted){returnmessage;}}}document.ready=function(){$('form[data-validate-exit="true"]').find('button[type="submit"]').click(function(){window.isSubmitted=true;});}
The message doesn’t show on firefox, but a convenient one will show, enough to warn the user on his actions.
The html code in your form should be like this:
123
<formdata-validate-exit="true"> Your html here
</form>
One friendly suggestion if you follow this path, after you implement this on any of your web apps, use Opera for development, or comment the stuff out for your own sake, you will loose your mind clicking on the leave validations.