Don't stop on Rails TestTask failure - ruby-on-rails

I'm adding a test task in my Rakefile, similar to this:
namespace :test do
desc "Test lib source"
Rake::TestTask.new(:lib) do |t|
t.libs << "test"
t.pattern = 'test/lib/**/*_test.rb'
t.verbose = true
end
end
and then adding (have also done using "enhance" with the same result:
task :test => [ 'test:lib' ]
My problem is that if there is an error encountered in test:lib, the suite stops running. That's not a terrible thing, but ideally it would go on to run the rest of the suite to let me know that there are more issues later in the suite.
Anyone know how to make it report the errors/failures in test:lib but go on to run the full suite?
Thanks!

Used something along these lines (minus the "on the fly" bit):
http://toolmantim.com/articles/creating_rake_testtasks_on_the_fly

Related

Sidekiq jobs won't run in same time in different queues

I have 2 Sidekiq workers:
Foo:
​# frozen_string_literal: true
class FooWorker
include Sidekiq::Worker
sidekiq_options queue: :foo
def perform
loop do
File.open(File.join(Rails.root, 'foo.txt'), 'w') { |file| file.write('FOO') }
end
end
end
Bar:
# frozen_string_literal: true
class BarWorker
include Sidekiq::Worker
sidekiq_options queue: :bar
def perform
loop do
File.open(File.join(Rails.root, 'bar.txt'), 'w') { |file| file.write('BAR') }
end
end
end
Which has pretty the same functionality, both runs on different queues and the yaml file looks like this:
---
:queues:
- foo
- bar
development:
:concurrency: 5
The problem is, even both are running and showing in the Busy page of Sidekiq UI, only one of them will actually create a file and put contents in. Shouldn't Sidekiq be multi-threaded?
Update:
this happens only on my machine
i created a new project with rails new and same
i cloned a colleague project and ran his sidekiq and is working!!!
i used his sidekiq version, not working!
New Update:
this happens also on my colleague machine if he clone my project
if I run 2 jobs with a finite loop ( like 10 times do something with a sleep), first job will be executed and then the second, but after the second finishes and start again both will work on same time as expected -- everyone who cloned the project from: github.com/ArayB/sidekiq-test encountered the problem.
It's not an issue with Sidekiq. It's an issue somewhere in Ruby/MRI/Thread/GIL. Google for more info, but my understanding is that sometimes threads aren't real threads (see "green threads") so really just simulate threading. The important thing is that only one thread can execute at a time.
It's interesting that with only two threads the system isn't giving time to the second thread. No idea why, but it must realize it's mistake when you run it again.
Interestingly if you run your same app but instead fire off 10 TestWorkers (and tweak the output so you can tell the difference) sidekiq will run all 10 "at once".
10.times {|i| TestWorker.perform_async(i) }
Here is the tweaked worker. Be sure to flush the output cause that can also cause issues with threading and TTY buffering not reflecting reality.
class TestWorker
include Sidekiq::Worker
def perform(n)
10.times do |i|
puts "#{n} - #{i} - #{Time.current}"
$stdout.flush
sleep 1
end
end
end
Some interesting links:
https://en.wikipedia.org/wiki/Green_threads
http://ruby-doc.org/core-2.4.1/Thread.html#method-c-pass
https://github.com/ruby/ruby/blob/v2_4_1/thread.c
Does ruby have real multithreading?

Appium: Ruby: Distributed tests with appium for iOS

I am having a fully fledged suite for automated tests written using ruby with Appium for mobile automation.
I am running these suites in one simulator in one machine and it takes up a lot of time, around 1 hour to run 56 test cases(We have system test cases where multiple checks like database/Api/functional are integrated). We have more additional test cases adding to our way.
We have implemented running our tests across 3 mac machines currently with running different cucumber tags integrated to Jenkins. However, more addition of tests is only going to take us more time or more mac's
With xcode 9 we can initiate multiple simulators on one machine at the same time, and I had like to know, if there is any sample scenario or documentation on how to implement distributed tests across simulators in one mac machine
I had tried loading two or three different desired capabilities with different platform version, but it only loads the tests in sequential order.
I had gone through a lot of material online that has only the steps to make this possible in android. Does iOS support it?
Or could anyone possibly provide links that would help me? to
1. Implement distributed tests across various simulators in one mac
2. Use cucumber tags to distribute tests creating instance for each desired capability
Update:
I had tried implementing the multithread option and tried to initiate the tests to specific simulator creating instance with each thread. However, I find the tests not running in parallel but sequential.
This is my code:
def start_app(device_id, wdalocalport)
caps_config = {
platformName: "iOS",
wdaLocalPort: wdalocalport,
deviceName: "iPhone Simulator", #update device as per your need
app: (File.join(File.dirname(__FILE__), "Sequoia.app")),
bundleId: "something",
automationName: "XCUITest",
xcodeOrgId: "something",
xcodeSigningId: "iPhone Developer",
#platformVersion: "10.2",
noReset: "true",
fullReset: "false",
showIOSLog: "true",
autoAcceptAlerts: "true",
showXcodeLog: "true",
useNewWDA: "true",
resetOnSessionStartOnly: "true",
udid: device_id }
appium_lib_config={ port: 4723 }
$opts={ caps: caps_config, appium_lib: appium_lib_config }
setup
end
def setup
#appium = Appium::Driver.new($opts)
#appium.start_driver
#Makes all appium_lib methods accessible from steps
#Starts appium driver before the tests begin
end
def test(device1,device2)
threads = []
threads << Thread.new {
start_app(device1, '8100')
}
threads << Thread.new {
start_app(device2, '8200')
}
threads.each(&:join)
end
end
I am calling the launch tests using the test method passing the udid's. The simulators launch at the same time, and also installs the application at the same time, but the tests aren't parallel.
Any help to improvise this case?
I was able to use the rake to parallel run, but I still find this approach runs the tests in sequential manner or doesnt run at all
PFB the code
def run_cucumber(cucumber_options)
Cucumber::Rake::Task.new do |t|
t.cucumber_opts = cucumber_options
end
Rake::Task[:cucumber].invoke
end
task :iphone_7 do |t|
ENV['DEVICE'] = 'iphone7'
run_cucumber('-r features features/test.feature --format pretty --tags #slave1')
end
task :iphone_8 do |t|
ENV['DEVICE'] = 'iphone8'
run_cucumber('-r features features/test.feature --format pretty --tags #slave2')
end
multitask :all => [:iphone_7,:iphone_8]
My hooks.rb
Before do
check
end
def check
if ENV['DEVICE'] == 'iphone7'
start_app('iPhone6','port','udid')
elsif ENV['DEVICE'] == 'iphone8'
start_app('iphone6','port','udid')
else
puts "Device not"
end
end
I have been getting DEVICE NOT. Not sure what am I missing.
You need to create a method which invokes cucumber rake first in the Rakefile as follows:
def run_cucumber(cucumber_options)
Cucumber::Rake::Task.new do |t|
t.cucumber_opts = cucumber_options
end
Rake::Task[:cucumber].invoke
end
This method will need cucumber_options. You can pass same options as you pass on the command line like this:
-r features features/test.feature --format pretty --tags #test1
After this, define rake tasks for a particular configuration in the same Rakefile:
task :iphone_7 do |t|
ENV["DEVICE"] = "iphone 7"
run_cucumber('-r features features/test.feature --format pretty --tags #test1')
end
task :iphone_8 do |t|
ENV["DEVICE"] = "iphone 8"
run_cucumber('-r features features/test.feature --format pretty --tags #test2')
end
Here, ENV["DEVICE"] is used set to device config. You can use this variable in your env.rb in Before block to initialize the test. In Before block you can initialize devices based on this environment variable.
You can create rake tasks like this as many as you need.
Then you can invoke multiple tasks at the same time by using ruby's parallel gem. Examples are in this link -> Ruby Parallel gem
Just pass different types of rake task as the arguments in the Parallel object.
Eg:
task :run_parallel do |t|
Parallel.map([:iphone_7,:iphone_8]) {|task| Rake::Task[task].invoke }
end
And then trigger the run_parallel rake task to execute the whole code.
Eg:
bundle exec rake run_parallel

How to configure queue_classic logging

I couldn't find anywhere a solution on how to make queue_classic write logs to a file. Scrolls, which Queue_Classic uses for logging, doesn't seem to have any example either.
Could someone provide a working example?
The logging within the method called by QC will be the source for the logging. For example, in rails. Any call to Rails.logger will go to the log file appropriate to your RAILS_ENV. The log data coming from scrolls goes to stdout, so you could pipe STDOUT from your queues to a log file when you start them.
You could control your queues with god.rb giving a god.rb configuration instance similar to this (I've left your configuration for number of queues, directories, etc up to you):
number_queues.times do |queue_num|
God.watch do |w|
w.name = "QC-#{queue_num}"
w.group = "QC"
w.interval = 5.minutes
w.start = "bundle exec rake queue:work" # This is your rake task to start QC listening
w.gid = 'nginx'
w.uid = 'nginx'
w.dir = rails_root
w.keepalive
w.env = {"RAILS_ENV" => rails_env}
w.log = "#{log_dir}/qc.stdout.log" # Or.... "#{log_dir}//qc-#{queue_num}.stdout.log"
# determine the state on startup
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
end
end
end
end
FWIW, I find the STDOUT log data to be less than helpful and may end up just sending it to the bitbucket.
If the log data is useless, we should consider removing it.
DEBUG is very nice when I'm running it from a commandline. For times when I am trying to figure out what I've done to bork everything up (usually bundling issues, path issues, etc). Or times when I am going to demo what is going on in a queue.
For me, INFO logging consists of the standard lib=queue_classic level=info action=insert_job elapsed=16 message and any STDOUT/STDERR from forked executions or from PostgreSQL. I've not extended any of the logging classes since scrolls goes to STDOUT and my tasks are in an environment that provides logging.
Sure, it could be removed. I think that REALLY depends on the environment and what the queue is doing. If I were to be doing something that did not have Rails.logger then I would use the QC.log and scrolls more effectively and instrument my tasks in that manner.
As I play with it, I may keep my configuration as-is just because of the output coming from methods/applications called by the tasks themselves. I might decide to override QC.log code to add date/time. I am still working to determine what fits my needs.
Sorry, my last line was really focused on the environment example I had given.
original here: enter link description here

Testing interactive thor tasks

I have the following thor command:
require 'highline'
class Import < Thor
desc "files", "Import files into the database"
method_option "path", :required => true, :desc => "Path to folder containing new files", :aliases => "-p", :type => :string
def files
require './config/environment'
line = HighLine.new
line.say(line.color("Identified files as Version 15 (English)", :green))
if line.agree(line.color("Are you sure you want to import?", :yellow))
line.say(line.color("Finished. Imported 70,114 items", :green))
else
line.say(line.color("Aborting...", :red))
end
end
end
Now, obviously, at the moment this is just outputting some language to the screen. However, what I need to do is write a test for the command that tests the output is as I would expect, and that when I start hooking in the heavy lifting that I can stub that stuff out.
I've had a look at Aruba, but this doesn't appear to like interactivity for some reason, and it's not clear why.
Therefore, does anyone have any ideas on how this might be testable (with RSpec)?
Aruba is a pretty complete set of steps for testing command line apps. If it's not working for you it might be because aruba defaults all file operations into tmp/aruba.
But neimOo is right about how to write the scenario with aruba
When I run `thor import` interactively
And I type "yes"
Here is how you can do this with Aruba
Scenario: Test import
When I run `thor import` interactively
And I type "yes"
Then the stdout should contain "Finished. Imported 70,114 items"
Here you can find a lot of aruba examples
https://github.com/cucumber/aruba/blob/master/features/interactive.feature
And here is implementation itself
https://github.com/cucumber/aruba/blob/master/lib/aruba/cucumber.rb

How to build task 'db:populate'

1 namespace :db do
2 desc "Fill database with sample videos"
3 task :populate => :environment do
4 require 'faker'
5 Rake::Task['db:reset'].invoke
6 100.times do |n|
7 headline = Faker::Lorem.sentence(3)
8 video = Faker::Lorem.words(5)
9 Video.create!(:headline => headline,
10 :video => video)
11 end
12 end
13 end
I currently have this rake task in lib/tasks/sample_data.rb
When running rake db:populate I get the error, Don't know how to build task 'db:populate'. How do I get around this?
Notes:
I am a newbie in Rails/Ruby. I am using Rails 3.
Try renaming the file to sample_data.rake.
I was able to get your example working (replacing the internals of the task with a p statement) by putting your code in a file called testomatic.rake in lib/tasks.
I also had this problem. In Finder, the file name was sample_data.rake, but upon clicking "Get Info" for the file, I discovered the full file name was sample_data.rake.erb -- ensure that's not your problem.
Noobie with the same problem here - my branch was named differently than what I thought when I merged branches, so it reverted back to the old files before I had created my lib/tasks/sample_data.rake file.
Simply going back and re-running git merge with the correct name and pushing to Heroku got it to work.

Resources