I'm new to TDD on Rails and I want the right tools. TestUnit+Spork+Guard seems perfect to me, but I can't make it work. The setup seems right, but when I launch Guard, this happens :
Ruff% guard --debug
16:08:59 - DEBUG - Command execution: which notify-send
16:08:59 - DEBUG - Command execution: emacsclient --eval '1' 2> /dev/null || echo 'N/A'
16:08:59 - INFO - Guard is using NotifySend to send notifications.
16:08:59 - INFO - Guard is using TerminalTitle to send notifications.
16:08:59 - DEBUG - Command execution: hash stty
16:08:59 - DEBUG - Guard starts all plugins
16:08:59 - DEBUG - Hook :start_begin executed for Guard::Spork
16:08:59 - DEBUG - Command execution: ps aux | grep -v guard | awk '/spork/&&!/awk/{print $2;}'
16:08:59 - DEBUG - Killing Spork servers with PID:
16:08:59 - INFO - Starting Spork for Test::Unit
16:08:59 - DEBUG - guard-spork command execution: ["exec", "spork", "testunit", "-p", "8988"]
Using TestUnit, Rails
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8988!
16:09:05 - INFO - Spork server for Test::Unit successfully started
16:09:05 - DEBUG - Command execution: notify-send Spork Test::Unit successfully started -t 3000 -h int:transient:1 -i /home/simplonco/.rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/guard-2.3.0/images/success.png -u low
16:09:05 - DEBUG - Hook :start_end executed for Guard::Spork
16:09:05 - DEBUG - Hook :start_begin executed for Guard::Test
16:09:05 - INFO - Guard::Test 2.0.4 is running, with Test::Unit 2.5.5!
16:09:05 - INFO - Running all tests
16:09:05 - INFO - Using testdrb to run the tests
16:09:05 - DEBUG - Command execution: testdrb -I"lib:test"
Running tests with args ["-Ilib:test"]...
Usage: testrb [options] tests...
Error: exit code 1
Done.
"Error: exit code 1" is making me crazy, Guard won't launch the tests. I found nobody with the same problem.
When I modify a file, Guard recognize it and launch himself. Then this happens :
10:51:42 - DEBUG - Hook :run_on_modifications_end executed for Guard::Test
10:51:42 - DEBUG - Start interactor
10:58:06 - DEBUG - Stop interactor
10:58:06 - DEBUG - Hook :run_on_modifications_begin executed for Guard::Test
10:58:06 - INFO - Running: test/models/user_test.rb
10:58:06 - DEBUG - Command execution: testdrb -I"lib:test"
Running tests with args ["-Ilib:test"]...
Usage: testrb [options] tests...
Error: exit code 1
Done.
I spend a lot of time on guard's documentation, can't find anything. Bundle exec guard don't work better. I tried to make a new app from scratch : "Error: exit code 1" again.
My Guardfile :
guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' },
:rspec_env => { 'RAILS_ENV' => 'test' } do
watch('Gemfile')
watch('config/application.rb')
watch('config/environment.rb')
watch('config/environments/test.rb')
watch(%r{^config/initializers/.+\.rb$})
watch('Gemfile.lock')
watch('spec/spec_helper.rb') { :rspec }
watch('test/test_helper.rb') { :test_unit }
watch(%r{features/support/}) { :cucumber }
end
guard :test, drb: true do
watch(%r{^test/.+_test\.rb$})
watch('test/test_helper.rb') { 'test' }
# Non-rails
watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
# Rails 4
watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" }
watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' }
watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" }
watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" }
end
The test group of my gemfile :
group :test do
gem 'turn'
gem 'guard-test'
gem 'guard-livereload'
gem 'guard-spork'
gem 'spork-rails'
gem 'spork-testunit'
end
Looking at spork-testunit I see that the expected usage is
testdrb -Itest test/your_test.rb
whereas Guard executes
testdrb -I"lib:test"
Comparing those two, I see that the Guard command lacks the path to the tests, this is why Spork complains:
Usage: testrb [options] tests...
Error: exit code 1
This looks to me like you have a Guard configuration or a project structure/test naming issue, but it's hard to tell without seeing your Guardfile and know something about your test files.
In general Guard::Test looks at your test path that is configured with the test_path option and is test by default. It then tries to find your test files by a specific pattern, which are then passed to the command execution. This is of course only true if you run all tests.
The patterns are:
Dir[File.join(path, '**', 'test_*.rb')] +
Dir[File.join(path, '**', '*_test{s,}.rb')]
So depending on your test file naming pattern, you can verify it in the rails console:
rails c
[1] pry(main)> Dir[File.join('test', '**', '*_test{s,}.rb')]
=> []
Here it fails for me, since I use RSpec, but it should return a list of all you test files if everything is fine.
Related
Whenever I call sh from rake it often echos the command that will be ran right before it is run. How can I prevent sh from logging the commands to stdout. I'd like to prevent this as I have api keys in the command I am calling, and I don't want to expose them in my build log.
There are two parts to solving this. The first is to pass the verbose: false option, which will prevent the command from being printed before it's executed:
$ cat Rakefile
SECRET = 'foobarbaz'
task :foo do
sh "echo #{SECRET} > secrets.txt", verbose: false
end
$ rake foo
(no output)
However, this doesn't help if there's an error, since Rake will print the failed command if it returns an error:
$ cat Rakefile
SECRET = 'foobarbaz'
task :foo do
sh "echo #{SECRET} > secrets.txt; exit 1", verbose: false
end
$ rake foo
rake aborted!
Command failed with status (1): [echo foobarbaz > secrets.txt; exit 1...]
...
The solution is hinted at in the docs for sh:
If a block is given, upon command completion the block is called with an OK flag (true on a zero exit status) and a Process::Status object. Without a block a RuntimeError is raised when the command exits non-zero.
You can see where the default behavior comes from in the Rake source. The solution, then, is to supply our own block:
$ cat Rakefile
SECRET = "foobarbaz"
task :foo do
sh "echo #{SECRET} > secrets.txt; exit 1", verbose: false do |ok, status|
unless ok
fail "Command failed with status (#{status.exitstatus}): [command hidden]"
end
end
end
$ rake foo
rake aborted!
Command failed with status (1): [command hidden]
...
Looks good!
If you find yourself needing this in multiple places, you could write a convenience method; something like this:
def quiet_sh(*cmd)
options = (Hash === cmd.last) ? cmd.pop : {}
options = { verbose: false }.merge(options)
sh *cmd, options do |ok, status|
unless ok
fail "Command failed with status (#{status.exitstatus}): [command hidden]"
end
end
end
SECRET = "foobarbaz"
task :foo do
quiet_sh "do_secret_things"
end
I believe this issue probably a duplicate of serverspec service test returns incorrect failure, but I include a bit more information of my execution environment.
I have a bunch of successful serverspec tests executing against a RHEL6 VM on AWS.
However any "service" test seems to fail with the matchers be_enabled and be_running.
I have the following in my spec_helper.rb:
set :os, :family => 'redhat', :release => '6', :arch => 'x86_64'
I tried both serverspec and rspec syntax for the tests and both fail as they run the same commands:
describe service('ntpd') do
it { should be_enabled }
it { should be_running }
end
it "is running ntpd" do
expect(service("ntpd")).to be_enabled
expect(service("ntpd")).to be_running
end
Failure/Error: it { should be_enabled }
expected Service "ntpd" to be enabled
sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ ntpd\ \|\ grep\ 3:on
Failure/Error: it { should be_running }
expected Service "ntpd" to be running
sudo -p 'Password: ' /bin/sh -c service\ ntpd\ status
However, running them locally on the server succeeds:
$ sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ ntpd\ \|\ grep\ 3:on
ntpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
$ echo $?
0
$ sudo -p 'Password: ' /bin/sh -c service\ ntpd\ status
ntpd (pid 1101) is running...
$ echo $?
0
I tried looking into setting up some debugging with pry-byebug but that looks not-so-straightforward, so I kind of gave up on that for now.
I'm running ruby 2.0, serverspec 2.24, rspec 3.3
Can anyone help point me in the right direction?
I needed to specify the runlevel to check, and then things worked. I presume this is some backwards compatibility issue between RHEL6/7 and systemV/systemD as the documentation indicates that the tests above should work.
describe service('ntpd') do
it { should be_enabled.with_level(2) }
it { should be_enabled.with_level(3) }
it { should be_enabled.with_level(4) }
it { should be_enabled.with_level(5) }
it { should be_running }
end
if the with level solution doesn't help, I also found that you need to set the PATH variable in the spec_helper.rb file to include /sbin and /usr/sbin. That did the trick for me personally.
It's my first time using azk in my development (Ruby 2.2.3 + Rails 4 project)
I want run the Rspec tests.
How I use Azkfile to create a specific system to test environment? (test gem's + test database + webkit dependencies)
Add the systems test andpostgres-test to your Azkfile.js as example below.
To run the provision you must use the start and then stop the system:
$ azk start -R test && azk stop test
$ azk shell -- bundle exec rspec spec
Or you can run the provision commands directly in the shell:
$ azk start postgres-test
$ azk shell test
bundle install --path /azk/bundler
bundle exec rake db:create
bundle exec rake db:migrate
$ azk shell -- bundle exec rspec spec
Example:
systems({
app: {
// ..
},
postgres: {
// ...
},
/* TEST */
test: {
extends: "app",
depends: ["postgres-test"],
command: "bundle exec rspec spec && exit 0",
provision: [
"bundle install --path /azk/bundler",
"bundle exec rake db:create",
"bundle exec rake db:migrate",
],
scalable: { default: 0, limit: 1 },
http: false,
wait: false,
envs: {
RAILS_ENV: "test",
RACK_ENV : "test",
BUNDLE_APP_CONFIG: "/azk/bundler",
HOST: "#{system.name}.#{azk.default_domain}",
},
},
"postgres-test": {
extends: "postgres",
scalable: { default: 0, limit: 1 },
envs: {
// set instances variables
POSTGRES_USER: "azk",
POSTGRES_PASS: "azk",
POSTGRES_DB : "#{manifest.dir}_test",
},
},
});
How do I run only Test 3 from the following tests?
module.exports = {
'Test 1':function(){},
'Test 2':function(){}
'Test 3':function(){}
}
A new parameter --testcase has been added to run a specified testcase.
nightwatch.js --test tests\demo.js --testcase "Test 1"
It's a new feature since the v0.6.0
https://github.com/beatfactor/nightwatch/releases/tag/v0.6.0
You must use specific tags before function and separate all functions in diferent files under tests directory, and then call command with --tag argument. See wiki nightwatch tags page and watch this example:
// --- file1.js ---
module.exports = {
tags: ['login'],
'Test 1':function(){
//TODO test 1
}
};
// --- file2.js ---
module.exports = {
tags: ['special', 'createUser'],
'Test 2':function(){
//TODO test 2
},
};
// --- file3.js ---
module.exports = {
tags: ['logoff', 'special'],
'Test 3':function(){
//TODO test 3
},
}
If you run:
nightwatch.js --tag login
only runs Test 1, however if you run:
nightwatch.js --tag special
Test 2 and Test 3 will be executed.
You can specific more than one tag
nightwatch.js --tag tag1 --tag tag2
Separate each test function is mandatory because Nightwatch handled with filematcher each file. See Github code.
PD: If file has syntax errors, is possible that test don't run or test hasn't been found
The --testcase flag can since version 0.6 be used to run a single test from the commandline, e.g.
nightwatch.js --test tests\demo.js --testcase "Test 1"
This could be done using either test groups or test tags. You can also execute a single test with the --test flag, e.g.
nightwatch.js --test tests\demo.js
For me, it only works with:
npm run test -- tests/01_login.js --testcase "Should login into Dashboard"
npm run <script> -- <test suite path> --testcase "<test case>"
my script in package.json:
"test": "env-cmd -f ./.env nightwatch --retries 2 --env selenium.chrome",
at nightwatch version 1.3.4
You can also use tags:
npm run <script> -- <enviroment> <tag>
npm run test -- --env chrome --tag login
just add it to your test case:
module.exports = {
'#tags': ['login', 'sanity', 'zero1'],
...
}
you can do somthing like:
node nightwatch.js -e chrome --test tests/login_test --testcase tc_001
Another possible way of doing so, would be to use the following on each test case that you want to omit:
'#disabled': true,
This can simply be set to false or removed if you wish to test it.
I have the following rb script which generate puppet facts according to the packages installed and which seems to be working ok in my puppet environment:
begin
pack = Facter::Core::Execution.execute('rpm -qa | grep ^ts')
packages = pack.split("\n")
packagehash = Hash.new
packages.each do |f|
packagehash[f.split("-")[0]] = f.split("-")[1] + ("-") + f.split("-")[2].split(".")[0]
end
rescue
end
begin
unless packagehash.empty?
packagehash.each_pair do |k,v|
Facter.add("bs_rpm_#{k}") {
setcode { "#{v}" }
}
end
end
rescue
end
I wrote the following spec which runs a small dummy test to see if my rspec env in general is ok:
require 'spec_helper'
describe 'bs package spec' do
before do
Facter.fact(:kernel).stubs(:value).returns("windows")
end
it "should run windows" do
Facter.fact(:kernel).value.should == "windows"
end
it "should create new facts" do
Facter::Core::Execution.stubs(:execute).with('rpm -qa | grep ^ts').returns('ts3_hostt01-1.0.0-34.x86_64\n')
Facter.fact(:bs_rpm_ts3_hostt01).value.should == "1.0.0-34"
end
end
But then when running rake spec I get the following error:
[dan#kyvltvm00022 bs_master]$ rake spec
/home/dan/.rvm/rubies/ruby-2.1.0/bin/ruby -S rspec spec/unit/facter/bs_package_spec.rb --color
.F
Failures:
1) bs package spec should create new facts
Failure/Error: Facter::Core::Execution.stubs(:execute).with('rpm -qa | grep ^ts').returns('ts3_hostt01-1.0.0-34.x86_64\n')
NameError:
uninitialized constant Facter::Core
# ./spec/unit/facter/bs_package_spec.rb:13:in `block (2 levels) in <top (required)>'
Finished in 0.00692 seconds
2 examples, 1 failure
Failed examples:
rspec ./spec/unit/facter/bs_package_spec.rb:12 # bs package spec should create new facts
/home/dan/.rvm/rubies/ruby-2.1.0/bin/ruby -S rspec spec/unit/facter/bs_package_spec.rb --color failed
[dan#kyvltvm00022 bs_master]$ exit
shell returned 1
[dan#kyvltvm00022 bs_master]$
What am I doing wrong or might be missing that is not loading Facter::Core ?? My spec_helper looks like this:
[dan#kyvltvm00022 bs_master]$ cat spec/spec_helper.rb
dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift File.join(dir, 'lib')
# Don't want puppet getting the command line arguments for rake or autotest
ARGV.clear
require 'puppet'
require 'facter'
require 'mocha'
gem 'rspec', '>=2.0.0'
require 'rspec/expectations'
require 'puppetlabs_spec_helper/puppet_spec_helper'
RSpec.configure do |config|
# FIXME REVISIT - We may want to delegate to Facter like we do in
# Puppet::PuppetSpecInitializer.initialize_via_testhelper(config) because
# this behavior is a duplication of the spec_helper in Facter.
config.before :each do
# Ensure that we don't accidentally cache facts and environment between
# test cases. This requires each example group to explicitly load the
# facts being exercised with something like
# Facter.collection.loader.load(:ipaddress)
Facter::Util::Loader.any_instance.stubs(:load_all)
Facter.clear
Facter.clear_messages
end
end
[dan#kyvltvm00022 bs_master]$
[UPDATE]
After checking my test system I noticed the facter gem was missing core so I updated the code and test as follows:
pack is now:
pack = Facter::Util::Resolution.exec('rpm -qa | grep ^ts')
and the stub in my test now is:
Facter::Util::Resolution.stubs(:exec).with('rpm -qa | grep ^ts').returns('ts3_hostt01-1.0.0-34.x86_64\n')
And the result now is this:
[dan#kyvltvm00022 bs_master]$ rake spec
/home/dan/.rvm/rubies/ruby-2.1.0/bin/ruby -S rspec spec/unit/facter/bs_package_spec.rb --color
.F
Failures:
1) bs package spec should create new facts
Failure/Error: Facter.fact(:bs_rpm_ts3_hostt01).value.should == "1.0.0-34"
NoMethodError:
undefined method `value' for nil:NilClass
# ./spec/unit/facter/bs_package_spec.rb:14:in `block (2 levels) in <top (required)>'
Finished in 0.00747 seconds
2 examples, 1 failure
Failed examples:
rspec ./spec/unit/facter/bs_package_spec.rb:12 # bs package spec should create new facts
/home/dan/.rvm/rubies/ruby-2.1.0/bin/ruby -S rspec spec/unit/facter/bs_package_spec.rb --color failed
[dan#kyvltvm00022 bs_master]$
What am i doing wrong in my test?
Looking through the facter code, this is the file you're requiring:
https://github.com/puppetlabs/facter/blob/master/lib/facter.rb
It doesn't require core/execution itself... without digging too much further in could you just try this in your spec_helper:
require 'facter/core/execution'