marbles.mixins

marbles.mixins

This module provides custom unittest-style assertions.

marbles.mixins.BetweenMixins()

Built-in assertions about betweenness.

marbles.mixins.MonotonicMixins()

Built-in assertions about monotonicity.

marbles.mixins.UniqueMixins()

Built-in assertions about uniqueness.

marbles.mixins.FileMixins()

Built-in assertions for files.

marbles.mixins.CategoricalMixins()

Built-in assertions for categorical data.

marbles.mixins.DateTimeMixins()

Built-in assertions for date s, datetime s, and time s.

This module provides custom unittest-style assertions. For the most part, marbles.mixins assertions trivially wrap unittest assertions. For example, a call to CategoricalMixins.assertCategoricalLevelIn() will simply pass the provided arguments to assertIn().

Custom assertions are provided via mixins so that they can use other assertions as building blocks. Using mixins, instead of straight inheritance, means that users can compose multiple mixins to create a test case with all the assertions that they need.

Warning

marbles.mixins can be mixed into a unittest.TestCase, a marbles.core.TestCase, a marbles.core.AnnotatedTestCase, or any other class that implements a unittest.TestCase interface. To enforce this, mixins define abstract methods. This means that, when mixing them into your test case, they must come after the class(es) that implement those methods instead of appearing first in the inheritance list like normal mixins.

Example:

import unittest

from marbles.core import marbles
from marbles.mixins import mixins


class MyTestCase(unittest.TestCase, mixins.BetweenMixins):

    def test_me(self):
        self.assertBetween(5, lower=0, upper=10)


class MyMarblesTestCase(marbles.TestCase, mixins.BetweenMixins):

    def test_me(self):
        self.assertBetween(5, lower=0, upper=10)
class marbles.mixins.BetweenMixins[source]

Built-in assertions about betweenness.

assertBetween(obj, lower, upper, strict=True, msg=None)[source]

Fail if obj is not between lower and upper.

If strict=True (default), fail unless lower < obj < upper. If strict=False, fail unless lower <= obj <= upper.

This is equivalent to self.assertTrue(lower < obj < upper) or self.assertTrue(lower <= obj <= upper), but with a nicer default message.

Parameters:
assertNotBetween(obj, lower, upper, strict=True, msg=None)[source]

Fail if obj is between lower and upper.

If strict=True (default), fail if lower <= obj <= upper. If strict=False, fail if lower < obj < upper.

This is equivalent to self.assertFalse(lower < obj < upper) or self.assertFalse(lower <= obj <= upper), but with a nicer default message.

Raises:

ValueError – If lower equals upper and strict=True is specified.

Parameters:
class marbles.mixins.CategoricalMixins[source]

Built-in assertions for categorical data.

This mixin includes some common categorical variables (e.g., weekdays, months, U.S. states, etc.) that test authors can use test resources against. For instance, if a dataset is supposed to contain data for all states in the U.S., test authors can test the state column in their dataset against the US_STATES attribute.

import unittest
from marbles.mixins import mixins


class MyTestCase(unittest.TestCase, mixins.CategoricalMixins):

    def test_that_all_states_are_present(self):
        df = ...
        self.assertCategoricalLevelsEqual(df['STATE'], self.US_STATES)

These categorical variables are provided as a convenience; test authors can and should manipulate these variables, or create their own, as needed. The idea is, for expectations that may apply across datasets, to ensure that the same expectation is being tested in the same way across different datasets.

WEEKDAYS
Type:

list

WEEKDAYS_ABBR

Weekdays abbreviated to three characters

Type:

list

MONTHS
Type:

list

MONTHS_ABBR

Months abbreviated to three characters

Type:

list

US_STATES
Type:

list

US_STATES_ABBR

U.S. state names abbreviated to two uppercase characters

Type:

list

US_TERRITORIES
Type:

list

US_TERRITORIES_ABBR

U.S. territory names abbreviated to two uppercase characters

Type:

list

CONTINENTS

7-continent model names

Type:

list

assertCategoricalLevelsEqual(levels1, levels2, msg=None)[source]

Fail if levels1 and levels2 do not have the same domain.

Parameters:
  • levels1 (iterable) –

  • levels2 (iterable) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:

TypeError – If either levels1 or levels2 is not iterable.

assertCategoricalLevelsNotEqual(levels1, levels2, msg=None)[source]

Fail if levels1 and levels2 have the same domain.

Parameters:
  • levels1 (iterable) –

  • levels2 (iterable) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:

TypeError – If either levels1 or levels2 is not iterable.

assertCategoricalLevelIn(level, levels, msg=None)[source]

Fail if level is not in levels.

This is equivalent to self.assertIn(level, levels).

Parameters:
  • level

  • levels (iterable) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:

TypeError – If levels is not iterable.

assertCategoricalLevelNotIn(level, levels, msg=None)[source]

Fail if level is in levels.

This is equivalent to self.assertNotIn(level, levels).

Parameters:
  • level

  • levels (iterable) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:

TypeError – If levels is not iterable.

class marbles.mixins.DateTimeMixins[source]

Built-in assertions for date s, datetime s, and time s.

assertDateTimesBefore(sequence, target, strict=True, msg=None)[source]

Fail if any elements in sequence are not before target.

If target is iterable, it must have the same length as sequence

If strict=True, fail unless all elements in sequence are strictly less than target. If strict=False, fail unless all elements in sequence are less than or equal to target.

Parameters:
  • sequence (iterable) –

  • target (datetime, date, iterable) –

  • strict (bool) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • ValueError – If target is iterable but does not have the same length as sequence.

  • TypeError – If target is not a datetime or date object and is not iterable.

assertDateTimesAfter(sequence, target, strict=True, msg=None)[source]

Fail if any elements in sequence are not after target.

If target is iterable, it must have the same length as sequence

If strict=True, fail unless all elements in sequence are strictly greater than target. If strict=False, fail unless all elements in sequence are greater than or equal to target.

Parameters:
  • sequence (iterable) –

  • target (datetime, date, iterable) –

  • strict (bool) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • ValueError – If target is iterable but does not have the same length as sequence.

  • TypeError – If target is not a datetime or date object and is not iterable.

assertDateTimesPast(sequence, strict=True, msg=None)[source]

Fail if any elements in sequence are not in the past.

If the max element is a datetime, “past” is defined as anything prior to datetime.now(); if the max element is a date, “past” is defined as anything prior to date.today().

If strict=True, fail unless all elements in sequence are strictly less than date.today() (or datetime.now()). If strict=False, fail unless all elements in sequence are less than or equal to date.today() (or datetime.now()).

Parameters:
Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If max element in sequence is not a datetime or date object.

assertDateTimesFuture(sequence, strict=True, msg=None)[source]

Fail if any elements in sequence are not in the future.

If the min element is a datetime, “future” is defined as anything after datetime.now(); if the min element is a date, “future” is defined as anything after date.today().

If strict=True, fail unless all elements in sequence are strictly greater than date.today() (or datetime.now()). If strict=False, fail all elements in sequence are greater than or equal to date.today() (or datetime.now()).

Parameters:
Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If min element in sequence is not a datetime or date object.

assertDateTimesFrequencyEqual(sequence, frequency, msg=None)[source]

Fail if any elements in sequence aren’t separated by the expected fequency.

Parameters:
  • sequence (iterable) –

  • frequency (timedelta) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If frequency is not a timedelta object.

assertDateTimesLagEqual(sequence, lag, msg=None)[source]

Fail unless max element in sequence is separated from the present by lag as determined by the ‘==’ operator.

If the max element is a datetime, “present” is defined as datetime.now(); if the max element is a date, “present” is defined as date.today().

This is equivalent to self.assertEqual(present - max(sequence), lag).

Parameters:
  • sequence (iterable) –

  • lag (timedelta) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If lag is not a timedelta object.

  • TypeError – If max element in sequence is not a datetime or date object.

assertDateTimesLagLess(sequence, lag, msg=None)[source]

Fail if max element in sequence is separated from the present by lag or more as determined by the ‘<’ operator.

If the max element is a datetime, “present” is defined as datetime.now(); if the max element is a date, “present” is defined as date.today().

This is equivalent to self.assertLess(present - max(sequence), lag).

Parameters:
  • sequence (iterable) –

  • lag (timedelta) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If lag is not a timedelta object.

  • TypeError – If max element in sequence is not a datetime or date object.

assertDateTimesLagLessEqual(sequence, lag, msg=None)[source]

Fail if max element in sequence is separated from the present by more than lag as determined by the ‘<=’ operator.

If the max element is a datetime, “present” is defined as datetime.now(); if the max element is a date, “present” is defined as date.today().

This is equivalent to self.assertLessEqual(present - max(sequence), lag).

Parameters:
  • sequence (iterable) –

  • lag (timedelta) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If sequence is not iterable.

  • TypeError – If lag is not a timedelta object.

  • TypeError – If max element in sequence is not a datetime or date object.

assertTimeZoneIsNone(dt, msg=None)[source]

Fail if dt has a non-null tzinfo attribute.

Parameters:
Raises:

TypeError – If dt is not a datetime object.

assertTimeZoneIsNotNone(dt, msg=None)[source]

Fail unless dt has a non-null tzinfo attribute.

Parameters:
Raises:

TypeError – If dt is not a datetime object.

assertTimeZoneEqual(dt, tz, msg=None)[source]

Fail unless dt’s tzinfo attribute equals tz as determined by the ‘==’ operator.

Parameters:
  • dt (datetime) –

  • tz (timezone) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If dt is not a datetime object.

  • TypeError – If tz is not a timezone object.

assertTimeZoneNotEqual(dt, tz, msg=None)[source]

Fail if dt’s tzinfo attribute equals tz as determined by the ‘!=’ operator.

Parameters:
  • dt (datetime) –

  • tz (timezone) –

  • msg (str) – If not provided, the marbles.mixins or unittest standard message will be used.

Raises:
  • TypeError – If dt is not a datetime object.

  • TypeError – If tz is not a timezone object.

class marbles.mixins.FileMixins[source]

Built-in assertions for files.

With the exception of assertFileExists() and assertFileNotExists(), all custom file assertions take a filename argument which can accept a file name as a str or bytes object, or a file-like object. Accepting a file-like object is useful for testing files that are not present locally, e.g., files in HDFS.

import unittest

import hdfs3
from marbles.mixins import mixins


class MyFileTest(unittest.TestCase, mixins.FileMixins):

    def test_file_encoding(self):
        fname = 'myfile.csv'

        # You can pass fname directly to the assertion (if the
        # file exists locally)
        self.assertFileEncodingEqual(fname, 'utf-8')

        # Or open the file and pass a file descriptor to the
        # assertion
        with open(fname) as f:
            self.assertFileEncodingEqual(f, 'utf-8')

    def test_hdfs_file_encoding(self):
        hdfspath = '/path/to/myfile.csv'

        client = hdfs3.HDFileSystem(host='host', port='port')
        with client.open(hdfspath) as f:
            self.assertFileEncodingEqual(f, 'utf-8')

Note that not all file-like objects implement the expected interface. These custom file assertions expect the following methods and attributes:

  • read()

  • write()

  • seek()

  • tell()

  • name

  • encoding

assertFileExists(filename, msg=None)[source]

Fail if filename does not exist as determined by os.path.isfile(filename).

Parameters:
assertFileNotExists(filename, msg=None)[source]

Fail if filename exists as determined by ~os.path.isfile(filename).

Parameters:
assertFileNameEqual(filename, name, msg=None)[source]

Fail if filename does not have the given name as determined by the == operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileNameNotEqual(filename, name, msg=None)[source]

Fail if filename has the given name as determined by the != operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileNameRegex(filename, expected_regex, msg=None)[source]

Fail unless filename matches expected_regex.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileNameNotRegex(filename, expected_regex, msg=None)[source]

Fail if filename matches expected_regex.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileTypeEqual(filename, extension, msg=None)[source]

Fail if filename does not have the given extension as determined by the == operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileTypeNotEqual(filename, extension, msg=None)[source]

Fail if filename has the given extension as determined by the != operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileEncodingEqual(filename, encoding, msg=None)[source]

Fail if filename is not encoded with the given encoding as determined by the ‘==’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileEncodingNotEqual(filename, encoding, msg=None)[source]

Fail if filename is encoded with the given encoding as determined by the ‘!=’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeEqual(filename, size, msg=None)[source]

Fail if filename does not have the given size as determined by the ‘==’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeNotEqual(filename, size, msg=None)[source]

Fail if filename has the given size as determined by the ‘!=’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeAlmostEqual(filename, size, places=None, msg=None, delta=None)[source]

Fail if filename does not have the given size as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero, or if their difference is greater than a given delta.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeNotAlmostEqual(filename, size, places=None, msg=None, delta=None)[source]

Fail unless filename does not have the given size as determined by their difference rounded to the given number ofdecimal places (default 7) and comparing to zero, or if their difference is greater than a given delta.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeGreater(filename, size, msg=None)[source]

Fail if filename’s size is not greater than size as determined by the ‘>’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeGreaterEqual(filename, size, msg=None)[source]

Fail if filename’s size is not greater than or equal to size as determined by the ‘>=’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeLess(filename, size, msg=None)[source]

Fail if filename’s size is not less than size as determined by the ‘<’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

assertFileSizeLessEqual(filename, size, msg=None)[source]

Fail if filename’s size is not less than or equal to size as determined by the ‘<=’ operator.

Parameters:
Raises:

TypeError – If filename is not a str or bytes object and is not file-like.

class marbles.mixins.MonotonicMixins[source]

Built-in assertions about monotonicity.

assertMonotonicIncreasing(sequence, strict=True, msg=None)[source]

Fail if sequence is not monotonically increasing.

If strict=True (default), fail unless each element in sequence is less than the following element as determined by the < operator. If strict=False, fail unless each element in sequence is less than or equal to the following element as determined by the <= operator.

assert all((i < j) for i, j in zip(sequence, sequence[1:]))
assert all((i <= j) for i, j in zip(sequence, sequence[1:]))
Parameters:
Raises:

TypeError – If sequence is not iterable.

assertNotMonotonicIncreasing(sequence, strict=True, msg=None)[source]

Fail if sequence is monotonically increasing.

If strict=True (default), fail if each element in sequence is less than the following element as determined by the < operator. If strict=False, fail if each element in sequence is less than or equal to the following element as determined by the <= operator.

assert not all((i < j) for i, j in zip(sequence, sequence[1:]))
assert not all((i <= j) for i, j in zip(sequence, sequence[1:]))
Parameters:
Raises:

TypeError – If sequence is not iterable.

assertMonotonicDecreasing(sequence, strict=True, msg=None)[source]

Fail if sequence is not monotonically decreasing.

If strict=True (default), fail unless each element in sequence is greater than the following element as determined by the > operator. If strict=False, fail unless each element in sequence is greater than or equal to the following element as determined by the >= operator.

assert all((i > j) for i, j in zip(sequence, sequence[1:]))
assert all((i >= j) for i, j in zip(sequence, sequence[1:]))
Parameters:
Raises:

TypeError – If sequence is not iterable.

assertNotMonotonicDecreasing(sequence, strict=True, msg=None)[source]

Fail if sequence is monotonically decreasing.

If strict=True (default), fail if each element in sequence is greater than the following element as determined by the > operator. If strict=False, fail if each element in sequence is greater than or equal to the following element as determined by the >= operator.

assert not all((i > j) for i, j in zip(sequence, sequence[1:]))
assert not all((i >= j) for i, j in zip(sequence, sequence[1:]))
Parameters:
Raises:

TypeError – If sequence is not iterable.

class marbles.mixins.UniqueMixins[source]

Built-in assertions about uniqueness.

These assertions can handle containers that contain unhashable elements.

assertUnique(container, msg=None)[source]

Fail if elements in container are not unique.

Parameters:
Raises:

TypeError – If container is not iterable.

assertNotUnique(container, msg=None)[source]

Fail if elements in container are unique.

Parameters:
Raises:

TypeError – If container is not iterable.