marvin/report/events.py
import time
"""Events that occur in Marvin"""
class EventType(object):
SUITE_STARTED = 10
SUITE_ENDED = 20
TEST_STARTED = 30
TEST_ENDED = 40
TEST_SETUP_STARTED = 50
TEST_SETUP_ENDED = 60
TEST_ITERATION_STARTED = 70
TEST_ITERATION_ENDED = 80
TEST_TEARDOWN_STARTED = 90
TEST_TEARDOWN_ENDED = 100
STEP_STARTED = 110
STEP_ENDED = 120
STEP_SKIPPED = 130
class Event(object):
"""Abstract root Event class"""
def __init__(self):
self._timestamp = int(time.time() * 1000)
@property
def timestamp(self):
"""Event timestamp (Unix time with ms granularity)"""
return self._timestamp
# -- SUITE related events --
class SuiteEvent(Event):
"""Abstract class for all Suite related events"""
def __init__(self, suite):
super(SuiteEvent, self).__init__()
self._suite = suite
@property
def suite(self):
"""The Suite instance associated with this event"""
return self._suite
class SuiteStartedEvent(SuiteEvent):
"""Triggered when a suite is about to start it's execution"""
event_type = EventType.SUITE_STARTED
class SuiteEndedEvent(SuiteEvent):
"""Triggered when a suite has finished it's execution"""
event_type = EventType.SUITE_ENDED
def __init__(self, suite, start_time, status):
super(SuiteEndedEvent, self).__init__(suite)
self._start_time = start_time
self._status = status
self._duration = self.timestamp - start_time
@property
def start_time(self):
"""The timestamp when the suite started"""
return self._start_time
@property
def duration(self):
"""The suite execution time in ms"""
return self._duration
@property
def status(self):
"""The suite's status"""
return self._status
# -- TEST related events --
class TestEvent(Event):
"""Abstract class for all TestScript related events"""
def __init__(self, test_script, data_provider):
super(TestEvent, self).__init__()
self._test_script = test_script
self._data_provider = data_provider
@property
def test_script(self):
"""The TestScript instance associated with this event"""
return self._test_script
@property
def data_provider(self):
"""The instance of the data provider driving this test execution"""
return self._data_provider
class TestStartedEvent(TestEvent):
"""Triggered when a test is about to start it's execution"""
event_type = EventType.TEST_STARTED
class TestEndedEvent(TestEvent):
"""Triggered when a test has finished it's execution"""
event_type = EventType.TEST_ENDED
def __init__(self, test_script, data_provider, start_time, status, exceptions):
super(TestEndedEvent, self).__init__(test_script, data_provider)
self._start_time = start_time
self._status = status
self._exceptions = exceptions
self._duration = self.timestamp - start_time
@property
def start_time(self):
"""The timestamp when the test started"""
return self._start_time
@property
def duration(self):
"""The test execution time in ms"""
return self._duration
@property
def status(self):
"""The test's status"""
return self._status
@property
def exceptions(self):
"""
The exceptions raised during this test. A list of 3-tuple items (like sys.exc_info)
composed of (Exception type, Exception instance, Traceback instance)
"""
return self._exceptions
class TestPhaseStartedEvent(TestEvent):
"""Abstract class for test's phase started: setup, iteration(s), tear down"""
def __init__(self, test_script, data_provider, data):
super(TestPhaseStartedEvent, self).__init__(test_script, data_provider)
self._data = data
@property
def data(self):
"""the data for this test phase"""
return self._data
class TestPhaseEndedEvent(TestEvent):
"""Abstract class for test's phase ended: setup, iteration(s), tear down"""
def __init__(self, test_script, data_provider, data, start_time, status, exception):
super(TestPhaseEndedEvent, self).__init__(test_script, data_provider)
self._data = data
self._start_time = start_time
self._status = status
self._exception = exception
self._duration = self.timestamp - start_time
@property
def data(self):
"""the data used by this test phase"""
return self._data
@property
def start_time(self):
"""The timestamp when the phase started"""
return self._start_time
@property
def duration(self):
"""The phase execution time in ms"""
return self._duration
@property
def status(self):
"""The phase's status"""
return self._status
@property
def exception(self):
"""
The exception raised by this phase (if any) as a 3-tuple (like sys.exc_info)
composed of (Exception type, Exception instance, Traceback instance)
"""
return self._exception
class TestSetupStartedEvent(TestPhaseStartedEvent):
"""Triggered when a test's setup phase is about to start"""
event_type = EventType.TEST_SETUP_STARTED
class TestSetupEndedEvent(TestPhaseEndedEvent):
"""Triggered when a test's setup phase has concluded"""
event_type = EventType.TEST_SETUP_ENDED
class TestIterationStartedEvent(TestPhaseStartedEvent):
"""Triggered when a test's iteration is about to start"""
event_type = EventType.TEST_ITERATION_STARTED
def __init__(self, test_script, data_provider, iteration):
super(TestIterationStartedEvent, self).__init__(test_script, data_provider, iteration.data)
self._iteration = iteration
@property
def iteration(self):
"""The IterationData instance with info about this iteration"""
return self._iteration
class TestIterationEndedEvent(TestPhaseEndedEvent):
"""Triggered when a test's iteration has concluded"""
event_type = EventType.TEST_ITERATION_ENDED
def __init__(self, test_script, data_provider, iteration, start_time, status, exception):
super(TestIterationEndedEvent, self).__init__(test_script, data_provider, iteration.data,
start_time, status, exception)
self._iteration = iteration
@property
def iteration(self):
"""The IterationData instance with info about this iteration"""
return self._iteration
class TestTearDownStartedEvent(TestPhaseStartedEvent):
"""Triggered when a test's tear down phase is about to start"""
event_type = EventType.TEST_TEARDOWN_STARTED
class TestTearDownEndedEvent(TestPhaseEndedEvent):
"""Triggered when a test's tear down phase has concluded"""
event_type = EventType.TEST_TEARDOWN_ENDED
# -- STEP related events --
class StepEvent(Event):
"""Abstract class for all Step related events"""
def __init__(self, step):
super(StepEvent, self).__init__()
self._step = step
@property
def step(self):
"""The step instance associated with this event"""
return self._step
class StepStartedEvent(StepEvent):
"""Triggered when a Step is about to be executed"""
event_type = EventType.STEP_STARTED
def __init__(self, step, args, kwargs):
super(StepStartedEvent, self).__init__(step)
self._args = args
self._kwargs = kwargs
@property
def args(self):
"""The arguments being passed to the step's run method"""
return self._args
@property
def kwargs(self):
"""The keyword arguments being passed to the step's run method"""
return self._kwargs
class StepEndedEvent(StepEvent):
"""Triggered when a Step has finished it's execution"""
event_type = EventType.STEP_ENDED
def __init__(self, step, status, result, start_time, exception=(None, None, None)):
super(StepEndedEvent, self).__init__(step)
self._status = status
self._result = result
self._start_time = start_time
self._duration = self.timestamp - start_time
self._exception = exception
@property
def status(self):
"""The step's status"""
return self._status
@property
def result(self):
"""The step's returned result (wrapped in a Result instance)"""
return self._result
@property
def start_time(self):
"""The timestamp when the step started"""
return self._start_time
@property
def duration(self):
"""The step execution time in ms"""
return self._duration
@property
def exception(self):
"""
The exception raised by this step (if any) as a 3-tuple (like sys.exc_info)
composed of (Exception type, Exception instance, Traceback instance)
"""
return self._exception
class StepSkippedEvent(StepEvent):
"""Triggered when a step is being skipped"""
event_type = EventType.STEP_SKIPPED
def __init__(self, step, exception):
super(StepSkippedEvent, self).__init__(step)
self._exception = exception
@property
def exception(self):
"""
The corresponding ContextSkippedException containing the reason and stacktrace
as a 3-tuple (like sys.exc_info) composed of (Exception type, Exception isntance, Traceback instance)
"""
return self._exception