From 25ecd9068c099f98a7647efe7d63041ace5565d1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 6 Nov 2015 06:57:38 +0100 Subject: [PATCH] tests: Don't wait for the same line twice. We need to search for lines in the history because we could miss something otherwise, but for subsequent wait_for calls, we really don't want to wait for the same thing again. This should make test_backforward.py more stable as it *actually* waits when going back now. Before, it did produce failures such as this one on OS X: ____________________________ test_going_backforward ____________________________ [..] @bdd.then(bdd.parsers.parse("The requests should be:\n{pages}")) def list_of_loaded_pages(httpbin, pages): requests = [httpbin.Request('GET', '/' + path.strip()) for path in pages.split('\n')] > assert httpbin.get_requests() == requests E assert [Request(verb...rward/1.txt')] == [Request(verb=...rward/2.txt')] E At index 3 diff: Request(verb='GET', path='/data/backforward/1.txt') != Request(verb='GET', path='/data/backforward/2.txt') E Full diff: E [Request(verb='GET', path='/data/backforward/1.txt'), E Request(verb='GET', path='/data/backforward/2.txt'), E Request(verb='GET', path='/data/backforward/1.txt'), E - Request(verb='GET', path='/data/backforward/1.txt')] E ? ^ E + Request(verb='GET', path='/data/backforward/2.txt')] E ? ^ tests/integration/features/conftest.py:85: AssertionError --- tests/integration/test_testprocess.py | 20 ++++++++++++++++++-- tests/integration/testprocess.py | 18 ++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/tests/integration/test_testprocess.py b/tests/integration/test_testprocess.py index 0ad7e1240..6ef9f87ed 100644 --- a/tests/integration/test_testprocess.py +++ b/tests/integration/test_testprocess.py @@ -112,9 +112,25 @@ class TestWaitFor: def test_existing_message_previous_test(self, pyproc): """Make sure the message of a previous test gets ignored.""" - pyproc.code = "time.sleep(0.1); print('foobar')" + pyproc.code = "print('foobar')" pyproc.start() - pyproc.wait_for(data="foobar") + # We can't use wait_for here, as that'd actually test what the next + # test does. + time.sleep(0.5) pyproc.after_test() with pytest.raises(testprocess.WaitForTimeout): pyproc.wait_for(data="foobar", timeout=100) + + def test_existing_message_already_waited(self, pyproc): + """Make sure an existing message doesn't stop waiting twice. + + wait_for checks existing messages (see above), but we don't want it to + automatically proceed if we already *did* use wait_for on one of the + existing messages, as that makes it likely it's not what we actually + want. + """ + pyproc.code = "time.sleep(0.1); print('foobar')" + pyproc.start() + pyproc.wait_for(data="foobar") + with pytest.raises(testprocess.WaitForTimeout): + pyproc.wait_for(data="foobar", timeout=100) diff --git a/tests/integration/testprocess.py b/tests/integration/testprocess.py index 4d516bdab..8f0ba1bb6 100644 --- a/tests/integration/testprocess.py +++ b/tests/integration/testprocess.py @@ -52,10 +52,12 @@ class Line: Attributes: data: The raw data passed to the constructor. + waited_for: If Process.wait_for was used on this line already. """ def __init__(self, data): self.data = data + self.waited_for = False def __repr__(self): return '{}({!r})'.format(self.__class__.__name__, self.data) @@ -209,15 +211,19 @@ class Process(QObject): The matched line. """ # Search existing messages - for item in self._data: + for line in self._data: matches = [] for key, expected in kwargs.items(): - value = getattr(item, key) + value = getattr(line, key) matches.append(self._match_data(value, expected)) - if all(matches): - return item + if all(matches) and not line.waited_for: + # If we waited for this line, chances are we don't mean the + # same thing the next time we use wait_for and it matches + # this line again. + line.waited_for = True + return line # If there is none, wait for the message spy = QSignalSpy(self.new_data) @@ -241,4 +247,8 @@ class Process(QObject): matches.append(self._match_data(value, expected)) if all(matches): + # If we waited for this line, chances are we don't mean the + # same thing the next time we use wait_for and it matches + # this line again. + line.waited_for = True return line