Testing a Protocol Class

Discussion in 'Ruby' started by Bill Atkins, Apr 11, 2004.

  1. Bill Atkins

    Bill Atkins Guest

    I'm in the process of writing a series of classes to connect to an AOL
    OSCAR server (the servers used by AIM), but I'm not quite sure how to
    set up tests for the classes. Basically, what I have now is a test.rb
    file that creates a new thread to run a mock OSCAR server. The test
    code then connects to the mock server and does its thing. I then
    check the log messages to see if the authentication and such have gone
    as they should.

    I'd like some way to use Test::Unit to run unit tests for this
    project, but I'm not entirely sure how to do that, since I can't test
    individual methods unless there are sockets set up for transfer. Is
    my mock server approach appropriate or is there some other way to do
    unit testing for a protocol client?

    Bill Atkins
    Bill Atkins, Apr 11, 2004
    #1
    1. Advertising

  2. Bill Atkins

    Bill Kelly Guest

    Hi,

    From: "Bill Atkins" <>

    > I'm in the process of writing a series of classes to connect to an AOL
    > OSCAR server (the servers used by AIM), but I'm not quite sure how to
    > set up tests for the classes. Basically, what I have now is a test.rb
    > file that creates a new thread to run a mock OSCAR server. The test
    > code then connects to the mock server and does its thing. I then
    > check the log messages to see if the authentication and such have gone
    > as they should.
    >
    > I'd like some way to use Test::Unit to run unit tests for this
    > project, but I'm not entirely sure how to do that, since I can't test
    > individual methods unless there are sockets set up for transfer. Is
    > my mock server approach appropriate or is there some other way to do
    > unit testing for a protocol client?


    I test my own network code similarly. The closest situation
    I have to yours is probably my IRC client.

    I do have one situation, testing higher level code, where I
    run a mock IRC server in a separate thread. But that's when
    I'm testing "application" code that's using my IRC client
    class. For testing the IRC client itself, I (effectively)
    run the client on a separate thread, and mock the server
    with direct print() and gets() from the test functions.

    Essentially:

    SERVER_HOST = "localhost"
    SERVER_PORT = 12345

    def test_irccomm
    # This is creating the "mock IRC server" on localhost
    server = TCPServer.new(SERVER_PORT)

    # Here I'm starting up the IRC client handler that I
    # want to test, pointing it at my "mock server"...

    # Note that my IRC client does its i/o in a background
    # thread, which is why I said I "effectively" run
    # the client on a separate thread. . . . If the client
    # did blocking i/o in the foreground, then presumably
    # we'd create a separate thread here in which to place
    # the client. Because it's the mock server that I
    # want to be in the "foreground" here...
    cbh = TestIRCCallbackHandler.new
    irc = IRCComm.new(SERVER_HOST, SERVER_PORT, cbh)

    # Tell the client to initiate a connection.
    # Note that the connect method doesn't wait for
    # a result, it just makes the socket connection to
    # the server, and issues the appropriate first
    # registration handshake.
    assert( irc.eof )
    irc.connect(NICK1, USER, FULLNAME, USER_HOST)
    assert( ! irc.eof )

    # Now our "mock server" will accept the connection...
    sv_client = server.accept
    # ...and respond with some initial boilerplate:
    send_connect_notice(sv_client)

    # Now the mock server verifies the client sent the
    # correct initial connection info:
    assert_equal( "NICK #{NICK1}\r\n", sv_client.gets )
    assert_equal( "USER #{USER} #{USER_HOST} #{SERVER_HOST} :#{FULLNAME}\r\n", sv_client.gets )

    # The mock server responds with a problem:
    sv_client.print ":#{SERVER_HOST} 433 * #{NICK1} :Nickname is already in use.\r\n"

    # This is a hack for testing purposes... Added a waitio
    # method in the client to force it to deal with the
    # server response, before we continue...
    irc.waitio

    # The mock server verifies the client has responded
    # with a "second choice" nickname...
    assert_equal( "NICK #{NICK2}\r\n", sv_client.gets )

    # . . . etc . . .

    end



    Anyway... hope this helps. I have several networking classes
    I test with Test::Unit and they all seem to work out something
    like the above, with the "mock server" in the foreground doing
    the print() gets() assert() calls, and the client effectively
    in the background.


    Regards,

    Bill
    Bill Kelly, Apr 11, 2004
    #2
    1. Advertising

  3. Hello Bill,

    I would suggest to use a separate class that abstracts from the
    transportation layer (TCP) and has a functional interface that
    corresponds 1:1 with the protocol commands.

    Testing the transportation layer is another test case and should
    include all the possible failure problems on a network.

    Mixing both testcases into a huge one makes testing much harder, and
    takes more lines of code to implement.

    --
    Best regards,
    Lothar mailto:
    Lothar Scholz, Apr 11, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,736
    Thomas Weidenfeller
    Oct 12, 2005
  2. Edvard Majakari
    Replies:
    4
    Views:
    681
    Edvard Majakari
    Feb 25, 2005
  3. Brian van den Broek
    Replies:
    3
    Views:
    837
    Jeremy Bowers
    Apr 3, 2005
  4. Brian van den Broek
    Replies:
    2
    Views:
    387
    Brian van den Broek
    Apr 5, 2005
  5. Chris

    Testing and Load Testing

    Chris, Mar 4, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    322
Loading...

Share This Page