How to stub and mock interactive ruby app with Cucumber? - ruby

I have an interactive CLI app based on Highline gem. I can run it interactively for Cucumber tests using Aruba. But I can't using stubs and mocks, because Aruba starts my app as a child process. If I try to use Aruba::InProcess feature, it loses interactivity.
I have no idea any more. In what way can I testing such app?

What exactly do you want to stub and mock?
Cucumber is primarily used for integration testing, i.e. testing from end-user's point of view. End-users use the app through its interface, that's why cucumber does not provide easy ways of stubbing and mocking the app's internals and you should not do it either, at least not with cucumber.
Consider using fixtures for cucumber or unit testing with rspec.
If you want to stub out responses from 3rd parties, then you can use webmock gem to intercept requests and return fixtures as a response or fakefs to do the same for the filesystem.

Ok, I take that: Cucumber is not about stubs and mocks. And interactive CLI apps is, probably, the best example for it.
So, while you need interactivity, Cucumber through Aruba starts your app in a child process. And the only way for affect it, I find, is environment variables usage. For example, by setting variable with values 'production'/'development'/'test' I can change configuration of my app to using test DB instead of production etc.

Related

Testing Angular with Protractor on a Sinatra server?

I am curious as to how best to set up a testing environment for Angular on a server that is running Sinatra. Normally when running a node server, you have a package.json which can require the dev-dependency of Protractor. However a Sinatra server will only have a Gemfile. Are there any best practices or gems that facilitate using Protractor in a Ruby environment?
Protractor is a node application so you must have node install to use it. In your case it's sounds like you will need to have both the Gemfile to maintain the dependencies for the Sinatra app and a package.json to manage dependencies for your automation tests Protractor.
You have lots of other options for end to end tests in ruby if you don't want to or don't have to use Protractor you can use rspec (the syntax for rspec and jasmine is similar) or cucumber as your testing framework and then use capybara (or selenium directly if you prefer) to control a browser and complete end to end tests.

AngularJS Testing: Protractor, Karma, Jasmine in a Yeoman App

I use this yeoman generator:
https://github.com/Swiip/generator-gulp-angular
It installs three testing applications: Jasmine, Karma , Protractor
According to this article (Should I be using Protractor or Karma for my end-to-end testing?), I should use: Karma for small tests of e.g. a single controller. Protactor if I want to test the whole app and simulate an user browsing through my app. According to this blog (http://andyshora.com/unit-testing-best-practices-angularjs.html) I would use Jasmine for unit testing and Karma for end-to-end integration tests.
I guess Jasmine is the language where tests are written and the other two execute the code, is that correct? Also if I never wrote a test which is more important to learn first/ to focus on?
Karma is a test-runner, so it runs your test.
Jasmine is the framework that let you write test
In my opinion in Angularjs you :
must unit-test services, because your business code is there.
should unit-test controller, because users actions are there.
may unit-test custom directives (if you plan to share that directive with others, it's a must)
Protractor is made for E2E testing (tests navigation like a real user).
It combines WebDriverJS with Jasmine and lets you write End-to-End tests (you simulate a real browser and taking real actions) with Jasmine syntax.
That kind of test is also really important in a web app.
You should not test everything, especially at the start of the project, those kinds of tests usually come with a high level of maintenance (i.e., when you change a screen you may have to change the test).
What I do is test the critical path and features.
I made a reading app, so in my case, it was login, sign up, payment, access book, and access reader.

Cucumber + DBUnit (ruby)

Has anyone ever done the Cucumber + DBUnit setup for ruby ? (I am particularly trying to use it with Calabash for mobile app testing.)
Ideally it sounds like I should be able to add an #Before hook in Cucumber, so that I could there load the test data that I want into the database, before I proceed with the tests. Otherwise it seems to me that I have no way to do data-driven testing.
Note: I do know about Scenario outlines, but I am not (only) looking to run my test with different parameters - rather, I need to bring my database in a known state before I run my tests.
Thanks in advance
Have you considered giving database_cleaner a shot? You can setup database_cleaner so that it cleans your database before each test or whole test suite. It also works nicely with Cucumber.

Testing a lot of external APIs in Rails

I'm developing a Rails app with a lot of dependencies on external APIs, for example Delicious.
All APIs share two workflows:
On the first call they are going to load all data since the beginning of time.
All following calls will load data filtered by the last execution time (if supported).
Testing them in real means I must create a test account for each API or at least use my private one. Even with VCR, because they would be called once. And my biggest problem: I would have to mess around a lot with Date's and Time's to emulate the two different workflows mentioned above. Though Timecop makes it really easy, it feels like a pain in the ass.
Another approach is to fake the API calls and their corresponding responses completely, but this means no real tests and furthermore I would never realize changes or problems with the APIs.
Any suggestions? Maybe a good combination of both ways?
Do both.
Start by mocking/stubbing everything in your regular run-frequently test suite. Do this for all the fine-grained model/controller testing.
Then add end-to-end testing (eg in integration tests) that cover usual workflow-scenarios that hit the real (test) servers.
Alternatively use a different test suite for the end-to-end testing eg cucumber instead of Test::Unit, or selenium/Watir whatever as long as it's different to your usual test suite

Performing semi-automated testing with ruby

I am writing an open source gem that interacts with an sms service. I want to test the interaction, however it needs account information and a phone number to run. It also needs feedback to determine if sms messages were being sent correctly. This causes two problems:
I can't put the account information in the test file, as the gem is open source and anyone could get to it.
I need the person running the test to give information to the script as it is running (eg checking the phone to see if a message was received).
What techniques or libraries are available that can help with this? I'm currently using rspec and making it prompt for parameters (using gets), however it is pretty cluncky at the moment. I can't be the first person using ruby to have this problem, and I feel that I'm missing a gem or something that solves this problem.
Use mocks
What are your tests testing, specifically? That a given login/password works? Probably not. Most likely you want to make sure your code reacts to the API properly. Therefore, I'd suggest mocking. Save the output of the API calls and use a mock service to return those responses. Then test. Your tests will be faster and less brittle as a happy side-effect.
More information on mocking with RSpec is here:
http://rspec.info/documentation/mocks/
Re 1) Why not just save configuration options in a YAML file and load them at the beginning of your tests?
Re 2) Are there maybe any web services for that? E.g. one where you can send a message to and query an API to see if it worked. I know this can be unreliable, but the same is true for a user's phone company network.
+1 for Mark Thomas' answer on mocking. Two more alternative mock object libraries for Ruby: FlexMock and Mocha

Resources