Struct is slow

R

Robert Klemme

I usually find that it really doesn't matter how fast things run if
they produce the wrong results.

Well, if it takes ages until you find out because you have to wait for
results... :)

SCNR

robert
 
R

Robert Klemme

I interpreted the two types of testing as follows.

Assume you have a method that expects a single non-negative integer
argument. You'll probably want to test that it behaves correctly
for the following:
foo(0) # edge case
foo(1) # typical call
foo(36) # random case from all values
foo(100000000) # large magnitude
foo(1023) # testing near powers of two
foo(1024)
foo(1025)

These tests will be designed to make sure that foo works correctly
on *expected* input.

Then there is the question about whether you should test:
foo(-1)
foo(nil)
foo("bogus")
foo("too", "many", :arguments)
foo()

and so on. These tests are throwing *unexpected* input at the
method. Bertrand Meyer in his writings about design by contract
programming would say that foo isn't obligated to do anything at
all when called with arguments that are outside its 'contract'.
If foo blows up on that input it isn't the failure of 'foo' but
instead is the failure of the caller to adhere to the contract.

So the philosophical question is should you extend foo's contract
to say that it will raise a particular exception (ArgumentError),
add the code to foo, and keep the tests or instead should you
decide that the tests are superfluous and instead focus on
better tests for the code that eventually calls foo (i.e. make
sure your code never calls foo incorrectly).

I would probably relax that a bit and say that a method should throw
*any* exception in case of irregular input. And yes, I would test that
and not correctness of calling code for a simple reason: you know the
method you write but you cannot possibly know (and test) all code that
will invoke your method.

Kind regards

robert
 
R

Robert Dober

Well, if it takes ages until you find out because you have to wait for
results... :)
OTOH if they run forever they cannot produce wrong results...
God am I silly tonight. (s/tonight//)
R.
 
R

Robert Dober

"Vive la France".shall.translate.to "Viva Italia"
"Je ne suis pas disponible".shall.translate.to "Gone fishing"

Now that is normally considered enough. But for my personal comfort
and anticipating problems and bugs inside my great plan of
implementation - experience speaking ;). I will add some tests very
closely related to the implementation. You see, something totally
opposed to the BDD thing.
E.g.

assert_kind_of? Enumeration, my_thingy.instance_variable_get("@words")
but better would be duck type tests
assert_respond_to? :each, my_thing.....
assert [:each, :map, :size] <= my_thingy.ivarget("@words").methods

Ah! You're talking about stories (integration tests in TDD), which specify
how the *system* behaves in terms of the *user*'s exeperience, vs.
specifications (unit tests in TDD), which specify how an *object* behaves
in terms of *another object*'s experience.[1]

The current RSpec trunk is actually taking this conversation to a really
cool place; the acceptance/integration tests are called "stories", and are
written in plain text, ideally even by the customer/client instead of the
developer, e.g.:

Story: translate languages while confusing nationalism
As an English speaker
I want to translate foreign languages into English
And mix up foreign countries
So that I can read it without needing maps, because
US Americans do not have maps, such as, the Iraq.

Scenario: General French text
Given the original text is "Je ne suis pas disponible"
And the original language is French
When I press the translate button
Then the new text should be "Gone fishing"

Scenario: French nationalism/country mention
Given the original text is "Vive la France"
And the original language is French
When I press the translate button
Then the new text should be "Vive Italia"

That's it. That's the exact format of a story. You'd then have code that
deals with the parameters in each step:

steps = StepGroup.new do |define|
define.given("the original text is \"$text\"") do |text|
@translator.set_text text
...etc...
end
end

On the other hand, your specs (unit tests in TDD) are written more
programmatically; the intended reader/writer is a developer, and it saves
having to write step groups:

# Parser#parse will return either a Nationalism or a Translatable object.
p = Parser.new:)french)
p.parse("Bon soir").should_be kind_of?(Translatable)
p.parse("Vive la France").should_be kind_of?(Nationalism)
lambda { p.parse("Hello, I must be going) }.should_raise
Exception::AlreadyEnglish

etc.

For more on plain-text stories, check out:

http://blog.davidchelimsky.net/articles/2007/10/21/story-runner-in-plain-english

or

http://rubyurl.com/2AS

[1] Stolen shamelessly from a recent David Chelimsky post to the
rspec-users list

--
Jay Levitt |
Boston, MA | My character doesn't like it when they
Faster: jay at jay dot fm | cry or shout or hit.
http://www.jay.fm | - Kristoffer

Thanx lot Jay gotta check that out, very interesting and witty post.
BTW I believe it was Falkner who said, "Stealing is all right if you
steal from the right people" ;).
R.
 
R

Robert Dober

Good idea to pull this into another tread!

Actually I have been thinking and I believe that what I want is
*three* testsuits for an application.
The spec tests, gotta check the RSpec Story interpreter out :)
The module tests and ...

Whenever I run my module tests I expect them to pass, they never did,
they never do and they never will. I however will stubbornly continue
to expect them to pass, no doubt, thus is human nature :(.
So they fail and I pass the worst moment in the dev. life cycle,
either I shoot up the debugger (but I hate debugging) or I start to
instrument the code or I load the module into irb and walk the
datastructures, anyway whatever technique I use I do it too late.
I want to overcome my shortcomings I want to think about debugging
*before* it happens.
I'd love to have therefore ...

the micro tests or debugging test, a suit of strategically positioned
assertions, but not inside the code, but in a testsuit of its own.

Cheers
Robert
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top