-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is topic state shared between tests? #18
Comments
You should not change your topic. The topic is executed once, and the same object returned from the topic function is used to run all the defined specs in parallel. If you need this kind of thing, you need to make it sure that your specs are running sequentially, like this: @Vows.batch
class FixnumTest(Vows.Context):
def topic(self):
return Fixnum()
class Init:
def should_be_numeric(self, topic):
expect(topic.num).to_be_numeric()
def should_init_to_zero(self, topic):
expect(topic.num).to_equal(0)
class ChangingValue:
def topic(self, old_topic):
old_topic.num = 9
return old_topic
def should_be_able_to_change_number(self, topic):
expect(topic.num).to_equal(9)
... Each "class level" will execute sequentially and your tests will work. Give us your feedback when you solve your problem. |
That's because in order to use pyvows (as is true for vows.js, or even rspec
In the above test, the That's perfectly valid, because this way you only execute your code (which In pyVows if you do not define a topic for a given context, it will inherit Hope this all clarifies the situation. Cheers, |
I think this is very wrong. This creates a level of dependency between the tests, especially that they are running in parallel and can be very destructive. In my opinion every test should get a pristine copy of what the topic returns. The same goes for nested contexts (they should receive a pristine copy of what the parent topic returns. Look at the demonstration in rspec below. This is how tests should behave. Each apply the logic onto a pristine copy of the subject: class MyFixnum
attr_accessor :num
def initialize
@num = 0
end
def add(num)
@num += num
end
end
describe MyFixnum do
subject { MyFixnum.new }
it "should be 0 even outside the context" do
subject.num.should == 0
end
context 'init' do
it "should be 0" do
subject.num.should == 0
end
end
context 'setting' do
it "should allow me to set the num" do
subject.num = 9
subject.num.should == 9
end
it "should again be 0" do
subject.num.should == 0
end
end
context 'add' do
it { should respond_to :add }
it "should add to num" do
subject.num = 1
subject.add 2
subject.num.should == 3
end
it "should also be 0, adding to it should not change the pristine copy" do
subject.num.should == 0
end
end
it "should be 0 even outside the context and even at the end of all tests" do
subject.num.should == 0
end
end and the output: $ rspec -cf doc /tmp/my_fixnum.rb
MyFixnum
should be 0 even outside the context
should be 0 even outside the context and even at the end of all tests
init
should be 0
setting
should allow me to set the num
should again be 0
add
should respond to #add
should add to num
should also be 0, adding to it should not change the pristine copy
Finished in 0.0016 seconds
8 examples, 0 failures UPDATE: Added more tests to push the tests even further... |
This has broken 26 tests which is expected because tests were written to make the topic a single object shared between all tests, the team has to make a decision about which way should the tests be ran, sharing the same topic or with a pristine topic ? refs heynemann#18
I get what you are saying @eMxyzptlk. The issue here is the way Python deals with objects. In order to provide pyvows with pristine copies of the topic, we'd have to use deepcopy which is not reliable. (It’s also really slow…and one of the things we love about pyvows is that it’s FAST.) We used to do it with deepcopy, but we had very hard to debug issues with it. I'm not familiar with how this is done in Ruby (how RSpec manages to create a copy of the object). I'll give Thanks again for your feedback. Bernardo Heynemann |
Hey @heynemann, Thank you for your reply, the commit b0be6d8 above uses deepcopy to close the 3d23d10 failing test. However, this commit broke 26 tests (because they validate/uses the fact that the object does change between tests). My colleague (@duarnad) actually suggested something we could probably use to make those 26 tests pass again. We could make the pristine topic an optional feature, triggered by probably a tag like No problem, I fell in love with PyVows on first sight (really close to RSpec and I can't live without RSpec :)) very nice project and it deserves all the time and attention we can afford, Keep up the good Work!! Wael |
Thanks for the compliments ;) Implementing a decorator might be a good idea... Let me just think about it a little more, ok? Cheers, |
Thank you and please do take your time. Cheers /cc @duarnad |
I think I might know how RSpec does that, but I do not know if that is even possible in Python. What it does is:
I'm not sure if that's exactly how they do it, but it is one way because what's in the instance can't affect the ones outside the instance. You can read the code here https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/example_group.rb#L235-403 Anyway best of luck @heynemann If you need anything please let me know. Wael |
I'd really like to provide this capability, but still haven't had any success in finding a way of cloning the object between calls. Any ideas? |
can't you just run |
Hello,
I'm new to pyVows (and to Python for that matter). I'm coming from Ruby but need to develop a module for work. That said, I'm a bit confused to find out that the state of the tested object (the topic) is being shared between tests.
Look at the code and the test output to know exactly what I mean:
Am i doing something wrong ?
The text was updated successfully, but these errors were encountered: