I'm working on setting up some unit tests for this server I wrote, but
I'm having some difficulty wrapping my head around how this should
work with EM.
Typically you subclass your unit test from Test::Unit::TestCase,
right? So right now, I'm thinking something like this (to start):
require 'eventmachine'
require 'test/unit'
require 'assert2'
module UnitTestConnect
attr_accessor :name, :data_to_send, :response
def post_init
end
def connection_completed
send_data @data_to_send
end
def receive_data data
end
def unbind
end
end
class MyUnitTest < Test::Unit::TestCase
PORT = ARGV[0] || 9339
SERVER = ARGV[1] || '127.0.0.1'
def setup
EM::run { EM::connect(SERVER, PORT, UnitTestConnect) {|c| c.name =
"tester"; @conn = c } }
end
test_send_name
@data_to_send = "[name:#{@name}]"
# Somehow wait for response...
assert("named properly") { @response == "[named:#{@name}]"
end
def teardown
@@conn.close_connection
EM::stop_even_loop
end
end
Can/should I leverage EM::defer here somehow?
Thanks,
Steve
_______________________________________________
Eventmachine-talk mailing list
Eventmac...@rubyforge.org
http://rubyforge.org/mailman/listinfo/eventmachine-talk
See http://github.com/tmm1/em-spec/tree/master
It ensures a single reactor loop for all test cases in a given context.
I have a miniunit version I use as well.Please do ping if you're
interested.
- Lourens
check the tests in the test dir they might help you get on your way.
-=r
require "em-spec/rspec"
class YourTest <T::U::TC
include EM::SpecHelper
def test_something
em do
# your test code here
done
end
end
end
I have yet to try it with T::U, but there's no reason why it shouldn't
work. If you do give it a try, let me know how it turns out.
HTH,
Dan DeLeo
http://github.com/danielsdeleo/em-spec/tree/master
On Jun 4, 5:00 pm, Lourens Naudé <lour...@methodmissing.com> wrote:
> Steve H,
>
> Seehttp://github.com/tmm1/em-spec/tree/master
> > Eventmachine-t...@rubyforge.org
> >http://rubyforge.org/mailman/listinfo/eventmachine-talk
>
> _______________________________________________
> Eventmachine-talk mailing list
> Eventmachine-t...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/eventmachine-talk
Aman
This is similar to the way the EM tests are written, and does not
require the use of fibers at all, since EM.run is a blocking call:
def test_something
EM.run do
# your test code here
EM.stop
end
end
The advantage of using fibers and em-spec is that there is only one EM
loop running for all your tests, instead of one loop that is started
and stopped per test. This allows you to maintain some state across
tests (which might be considered a flaw, depending on your testing
philosophies).
Aman
Yep, that's the general idea and should work for both clients and
servers. If you're not testing any async code (i.e. passing in a block
to a function that is going to be invoked later), you don't need
fibers or em-spec. You can simply call send/receive_data and make sure
what you expect is happening.
If you do need to test callbacks, then fibers/em-spec are handy
because you can make your test 'wait' until the callback is called.
> Awesome.
> One more question: what exactly does the "EM.describe EventMachine do" call
> *do*? It runs the event loop? Something else?? I assume I should do
> "EM.describe MyServerModule do"... or is that incorrect?
Yes, you can pass in a string or a constant to describe based on what
you're testing behaviors for. EM.describe runs the event loop and
makes all test cases "pause" before moving onto the next test. You can
"resume" the test suite by calling done. This is handy because done
can be called from inside a callback that's called after some time.
describe 'timing' do
should 'wait 2 seconds' do
sleep 2
end
# won't get here until two seconds later
end
is emulated using
EM.describe 'timing' do
should 'wait 2 seconds' do
EM.add_timer(2){ done }
end
# won't get here until two seconds later
end
you can also do the same thing without fibers or em-spec (but you'll
have to start a reactor for each test):
describe 'timing' do
should 'wait 2 seconds' do
EM.run do
EM.add_timer(2){ EM.stop }
end
end
# won't get here until two seconds later
end
> Also: are we ensured order of the tests? I obviously didn't send this
> quickly enough, so let me respond to something you said below: using
> em-spec allows you to keep some state. That would be a huge advantage to
> me, if I could ensure tests were executed in order.
This is precisely the advantage you get with em-spec. The tests are
run in order, and since they all share the same reactor instance, you
can test things in order.. i.e. test connecting to a server, then
sending it data, then receiving certain types of responses, etc.
Without em-spec, you'd have to start a new reactor and connect to the
server for each test.
> Thanks!! :)
> -Steve
> PS: I'll let you guys know how it goes. There *are* some differences
> between EM servers and clients, so I won't exactly be able to duplicate your
> example and plug in my own classes, methods and tests. Right?
Yep, the basic ideas should remain the same. Good luck, let us know if
you have more questions.