Interval between tests in pytest - sleep

Is there a common practice to add interval between tests in pytest? Currently integration tests fail but work fine if running the tests individually.

You can use autouse fixtures in pytest to automatically sleep in between test cases:
#pytest.fixture(autouse=True)
def slow_down_tests():
yield
time.sleep(1)
This fixture will automatically be used for all test cases and will yield execution to a test case so it can run normally, but when the test finishes, the execution will come back to this fixture and the sleep will be run.

If you want a teardown in a module for every function of the module:
import time
def teardown_function(function): # the function parameter is optional
time.sleep(3)
If you want a teardown in a class for every method of the class, you've two options.
In this you can't access the invoked method:
class TestClass:
def teardown(self):
time.sleep(1)
If you need to access it:
class TestClass:
def teardown_method(self, method):
print(method)
time.sleep(1)
If you want a teardown that will be invoked once after a class:
#classmethod
def teardown_class(cls):
print(cls)
time.sleep(2)
All of this methods works in the same way for setups. You can see the documentation. Use fixtures for more complex implementations.

You can insert time.sleep(1) in the teardown method of each test, i.e:
class TestClass:
def setup(self):
pass
def teardown(self):
time.sleep(1) # sleep for 1 second

Related

How to define a class-level macro in a module in Ruby?

In the Ruby programming language, I am creating a class with a class-level macro, as follows:
class Timer
def self.add_time
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
The class method add_time, when executed, will generate a time method.
Now, I can execute that class-level macro in another class Example as follows:
class Example < Timer
add_time
end
When I now call time on an instance of class Example, the time method is present there, as I intended:
ex = Example.new
ex.time
and prints the current time: 23:18:38.
But now I would like to put the add_time macro in a module and still have the same overall effect. I tried with an include like this:
module Timer
def self.add_time
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
class Example
include Timer
add_time
end
ex = Example.new
ex.time
but then I receive an error that the method add_time is not defined on the class Example: NameError: undefined local variable or method ‘add_time’ for Example:Class. So then I tried with an extend instead like this:
class Example
extend Timer
add_time
end
but it gives me a similar error.
So the question is: How can I get the same effect as in my original example where the Timer was defined as a class, but using a module instead?
As #CarySwoveland pointed out, the method def self.add_time in the module Timer gets disregarded upon inclusion or extension in a class. Only the module's instance methods are added to the class as instance method of the class (in case of inclusion) or as class methods of the class (in case of extends).
module Timer
def add_time # INSTANCE METHOD !
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
So the first step of the solution is to declare the method def add_time as an instance method of the module. Next, we extend the class Example with that module, so that the module's instance method gets added as a class method in the class Example, and we call the add_timemethod:
class Example
extend Timer # EXTEND INSTEAD OF INCLUDE
add_time
end
However, this doesn't quite work as desired yet as the time method has now been generated as a class method: Example.time prints the current time 01:30:37, but an instance ex of class Example does not understand the method time.
The solution is thus to generate the method def time as an instance method rather than as a class method. This can be done using class_eval, which leads us to the following working solution:
module Timer
def add_time # INSTANCE METHOD !
self.class_eval do # USE class_eval TO DEFINE AN INSTANCE METHOD !
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
end
class Example
extend Timer # USE EXTEND TO ADD add_time AS A CLASS METHOD
add_time
end
ex = Example.new
ex.time

Running minitest produces no output

I have a file my_test.rb with the following contents:
require 'test/unit'
class MyTest < Test::Unit::TestCase
# Called before every test method runs. Can be used
# to set up fixture information.
def setup
# Do nothing
end
# Called after every test method runs. Can be used to tear
# down fixture information.
def teardown
# Do nothing
end
# Fake test
def dummy_test
print "Something!"
fail
end
end
When I run ruby my_test.rb, there is absolutely no output.
How can I run the unit tests in this file and see whether they are passing or failing?
There's nothing bad with your implementation and your actual code. But in order your dummy_test can execute what's inside its definition, it should be called first; thing you're not doing, that's why when you run your file you don't get any output.
You can create an example test, and there call your dummy_test method:
...
def test_something
dummy_test
end
# Fake test
def dummy_test
print "Something!"
fail
end
Test-unit will look for methods that start with “test” and use them as test methods. Your code has a method that ends with “test” but none that start with it, so it doesn’t see any tests to run.
Change the method name from dummy_test to test_dummy and you should see the output you are expecting.
As said before you are not calling on your function and therefore nothing will happen since ruby does not automatically execute the first / last function.
An example would be to implement this code
...
def main()
print "Something!"
end
main()
And if you would like to call a function which calls the other functions you will do the same
Example:
def main()
other_function1()
other_function2()
end
main()
And the other_functions would be other functions you define and call within the main function.

can common overriding code be shared

I am new to ruby and I'm hoping someone can help me. I am writing tests using test::unit and within my tests I needed to run some code before an assert was called so I overrided the assert methods like so:
class TestSomething < Test::Unit::TestCase
def assert_equal(expected, actual, message = nil)
mycode ..
super(expected, actual, message)
end
def assert(object, message)
my code ...
super(object, message)
end
def assert_not_nil(object, message = "")
my code ...
super(object, message)
end
def setup
end
def test_case1
end
def test_case1
end
def teardown
end
end
The above structure works fine and the asserts call my code. The thing is I have 100s of test classes. The assert overriding will be the same for all of them. Do I have to copy the assert overrides to the top of every class or is there a way for all of them to get the assert overrides in one go?
One more question. Is there a way of catching an error if it occurs anywhere within the entire class?
A
I am not sure why you do not want to use before filter, but the question as it was stated has an answer: since ruby classes are open, one might do the following.
class Test::Unit::TestCase
# store the original
alias_method :assert_equal_original, :assert_equal
# override
def assert_equal *args
# mycode ..
assert_equal_original *args
end
# the same for other methods
end
Once it is done, any derived class will call my_code before calling the original method.
To catch an error within the scope of the class is impossible, AFAIK.

Having more than one method in a sidekiq worker class

I have a sidekiq worker class. I currently implemented it this way. It works when I call PROCESS, and it will queue the method called PERFORM. But i would like to have more than one method that I can queue.
As a side note, is there a difference doing this and simply doing SocialSharer.delay.perform?
# I trigger by using SocialSharer.process("xxx")
class SocialSharer
include Sidekiq::Worker
def perform(user_id)
# does things
end
def perform_other_things
#i do not know how to trigger this
end
class << self
def process(user_id)
Sidekiq::Client.enqueue(SocialSharer,user_id)
end
end
end
SocialSharer.delay.perform would delay a class method called perform. Your perform method is an instance method.
Workers are designed to be one class per job. The job is started via the perform method. You can use delay to kick off any number of different class methods on a class, like so:
class Foo
def self.a(count)
end
def self.b(name)
end
end
Foo.delay.a(10)
Foo.delay.b('bob')
Well, if you really want to have all "performable" methods in one class, I'd suggest you to rename perform method to something different (say, perform_something), and create a new perform method which would dispatch the control flow:
class SocialSharer
include Sidekiq::Worker
# the 3 lines below may be replaced with `alias_method :perform, :public_send`
def perform(method, *args)
self.public_send(method, *args)
end
def perform_something(user_id)
# does things
end
def perform_other_things
# does other things
end
def self.process(user_id)
Sidekiq::Client.enqueue(SocialSharer, :perform_something, user_id)
Sidekiq::Client.enqueue(SocialSharer, :perform_other_things)
end
end

How to assert block of a mock in mocha

This example is contrived, please don't take it verbatim as my code.
I have the need to assert something like the following:
def mymethod
Dir.chdir('/tmp') do
`ls`
end
end
In the end I want to assert that:
Dir.chdir is invoked with the appropriate parameters.
` is invoked with the appropriate parameters
I started off with...
Dir.expects(:chdir).with('/tmp')
but after that I'm not sure how to invoke the block passed to Dir.chdir.
You need to use the mocha yields method. Also, writing an expectation for the backtick method is rather interesting. You need to make an expectation like this:
expects("`")
But on what object? You might think on Kernel or Object, but that doesn't actually work.
As an example, given this module:
module MyMethod
def self.mymethod
Dir.chdir('/tmp') do
`ls`
end
end
end
I could write a test like this:
class MyMethodTest < Test::Unit::TestCase
def test_my_method
mock_block = mock
mock_directory_contents = mock
MyMethod.expects("`").with('ls').returns(mock_directory_contents)
Dir.expects(:chdir).yields(mock_block).returns(mock_directory_contents)
assert_equal mock_directory_contents, MyMethod.mymethod
end
end
Part of the trick is to figure out which object to expect the backtick method to be invoked on. It depends on the context - whatever self is when that method is invoked. Here it is the module MyMethod, but depending on where you define mymethod it will be different.

Resources