Browse Source

module: add pytest for unit and snapshot testing with travis-ci

cn 8 months ago
parent
commit
6aabf21cf8
10 changed files with 3213 additions and 3 deletions
  1. 3
    0
      .gitignore
  2. 14
    0
      .travis.yml
  3. 2
    1
      README.md
  4. 4
    2
      bme280/__init__.py
  5. 2
    0
      pytest.ini
  6. 3
    0
      requirements.txt
  7. 0
    0
      tests/__init__.py
  8. 133
    0
      tests/bme280_test.py
  9. 0
    0
      tests/snapshots/__init__.py
  10. 3052
    0
      tests/snapshots/snap_bme280_test.py

+ 3
- 0
.gitignore View File

@@ -1 +1,4 @@
1
+.cache/
2
+env/
3
+__pycache__/
1 4
 *.pyc

+ 14
- 0
.travis.yml View File

@@ -0,0 +1,14 @@
1
+---
2
+sudo: false
3
+language: python
4
+python:
5
+  - "2.7"
6
+  - "3.6"
7
+
8
+matrix:
9
+  fast_finish: true
10
+  allow_failures:
11
+    - python: "3.6"
12
+
13
+script:
14
+  - pytest

+ 2
- 1
README.md View File

@@ -1,6 +1,7 @@
1
-
2 1
 # python-bme280
3 2
 
3
+[![Build Status](https://travis-ci.org/cmur2/python-bme280.svg?branch=master)](https://travis-ci.org/cmur2/python-bme280)
4
+
4 5
 A Python library for accessing the [BME280 combined humidity and pressure](https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf) from Bosch via `python-smbus` using the I2C interface.
5 6
 
6 7
 Default settings are suitable for Raspberry Pi 2 and 3 and was successfully tested using a [breakout](https://github.com/watterott/BME280-Breakout).

+ 4
- 2
bme280/__init__.py View File

@@ -1,4 +1,6 @@
1 1
 
2 2
 from bme280 import Bme280
3
-#from bme280 import HO_SKIPPED, HO_1, HO_2, HO_4, HO_8, HO_16, PO_SKIPPED, PO_1, PO_2, PO_4, PO_8, PO_16, TO_SKIPPED, TO_1, TO_2, TO_4, TO_8, TO_16
4
-#from bme280 import MODE_SLEEP, MODE_FORCED, MODE_NORMAL
3
+from bme280 import HO_SKIPPED, HO_1, HO_2, HO_4, HO_8, HO_16, PO_SKIPPED, PO_1, PO_2, PO_4, PO_8, PO_16, TO_SKIPPED, TO_1, TO_2, TO_4, TO_8, TO_16
4
+from bme280 import MODE_SLEEP, MODE_FORCED, MODE_NORMAL
5
+from bme280 import TSTANDBY_0_5, TSTANDBY_62_5, TSTANDBY_125, TSTANDBY_250, TSTANDBY_500, TSTANDBY_1000, TSTANDBY_10, TSTANDBY_20
6
+from bme280 import FILTER_OFF, FILTER_2, FILTER_4, FILTER_8, FILTER_16

+ 2
- 0
pytest.ini View File

@@ -0,0 +1,2 @@
1
+[pytest]
2
+norecursedirs = env* .*

+ 3
- 0
requirements.txt View File

@@ -0,0 +1,3 @@
1
+mock==2.0.0
2
+pytest==3.0.6
3
+snapshottest==0.5.0

+ 0
- 0
tests/__init__.py View File


+ 133
- 0
tests/bme280_test.py View File

@@ -0,0 +1,133 @@
1
+
2
+# import unittest
3
+import sys
4
+import time
5
+
6
+import mock
7
+
8
+import snapshottest
9
+
10
+# Note: prepare globally mocked modules first and then load our module
11
+MOCKED_SMBUS_MODULE = mock.Mock()
12
+sys.modules['smbus'] = MOCKED_SMBUS_MODULE
13
+time.sleep = lambda s: None
14
+import bme280
15
+
16
+# inspired by https://github.com/adafruit/Adafruit_Python_GPIO/blob/master/Adafruit_GPIO/I2C.py
17
+class MockSMBus(object):
18
+    def __init__(self, initial_read=None):
19
+        self._log = []
20
+        self.initial_read = initial_read or {}
21
+
22
+    def read_byte(self, addr):
23
+        val = self.initial_read.get(addr).pop(0)
24
+        self._log.append(('r', addr, val))
25
+        return val
26
+
27
+    def write_byte(self, addr, val):
28
+        self._log.append(('w', addr, val))
29
+
30
+    def read_byte_data(self, addr, cmd):
31
+        val = self.initial_read.get(addr).pop(0)
32
+        self._log.append(('w', addr, cmd))
33
+        self._log.append(('r', addr, val))
34
+        return val
35
+
36
+    def write_byte_data(self, addr, cmd, val):
37
+        self._log.append(('w', addr, cmd))
38
+        self._log.append(('w', addr, val))
39
+
40
+def setup_mockbus(**kwargs):
41
+    mockbus = MockSMBus(**kwargs)
42
+    MOCKED_SMBUS_MODULE.SMBus.return_value = mockbus
43
+    return mockbus
44
+
45
+def calibration_read():
46
+    return [0x00] * (24+1+7)
47
+
48
+class TestBme280(snapshottest.TestCase):
49
+
50
+    def test_setup(self):
51
+        mockbus = setup_mockbus(initial_read={
52
+            0x76: calibration_read()
53
+        })
54
+        bme = bme280.Bme280()
55
+        MOCKED_SMBUS_MODULE.SMBus.assert_called_with(1)
56
+        self.assertIsNotNone(bme)
57
+        self.assertMatchSnapshot(mockbus._log)
58
+
59
+    def test_chip_id(self):
60
+        mockbus = setup_mockbus(initial_read={
61
+            0x76: calibration_read() + [0x23]
62
+        })
63
+        bme = bme280.Bme280()
64
+        self.assertEqual(bme.get_chip_id(), 0x23)
65
+        self.assertMatchSnapshot(mockbus._log)
66
+
67
+    def test_reset(self):
68
+        mockbus = setup_mockbus(initial_read={
69
+            0x76: calibration_read()
70
+        })
71
+        bme = bme280.Bme280()
72
+        bme.reset()
73
+        self.assertMatchSnapshot(mockbus._log)
74
+
75
+    def test_status(self):
76
+        mockbus = setup_mockbus(initial_read={
77
+            0x76: calibration_read() + [0x08, 0x00, 0x01, 0x00]
78
+        })
79
+        bme = bme280.Bme280()
80
+        self.assertTrue(bme.is_status_measuring())
81
+        self.assertFalse(bme.is_status_measuring())
82
+        self.assertTrue(bme.is_status_image_register_updating())
83
+        self.assertFalse(bme.is_status_image_register_updating())
84
+        self.assertMatchSnapshot(mockbus._log)
85
+
86
+    def test_oversampling(self):
87
+        mockbus = setup_mockbus(initial_read={
88
+            0x76: calibration_read()
89
+        })
90
+        bme = bme280.Bme280()
91
+        self.assertEqual(bme.get_humidity_oversampling(), bme280.HO_1)
92
+        bme.set_humidity_oversampling(bme280.HO_16)
93
+        self.assertEqual(bme.get_humidity_oversampling(), bme280.HO_16)
94
+        self.assertEqual(bme.get_temperature_oversampling(), bme280.TO_1)
95
+        bme.set_temperature_oversampling(bme280.TO_16)
96
+        self.assertEqual(bme.get_temperature_oversampling(), bme280.TO_16)
97
+        self.assertEqual(bme.get_pressure_oversampling(), bme280.PO_1)
98
+        bme.set_pressure_oversampling(bme280.PO_16)
99
+        self.assertEqual(bme.get_pressure_oversampling(), bme280.PO_16)
100
+        self.assertMatchSnapshot(mockbus._log)
101
+
102
+    def test_mode(self):
103
+        mockbus = setup_mockbus(initial_read={
104
+            0x76: calibration_read()
105
+        })
106
+        bme = bme280.Bme280()
107
+        self.assertEqual(bme.get_mode(), bme280.MODE_SLEEP)
108
+        bme.set_mode(bme280.MODE_FORCED)
109
+        self.assertEqual(bme.get_mode(), bme280.MODE_FORCED)
110
+        self.assertMatchSnapshot(mockbus._log)
111
+
112
+    def test_config(self):
113
+        mockbus = setup_mockbus(initial_read={
114
+            0x76: calibration_read()
115
+        })
116
+        bme = bme280.Bme280()
117
+        self.assertEqual(bme.get_tstandy(), bme280.TSTANDBY_1000)
118
+        bme.set_tstandy(bme280.TSTANDBY_20)
119
+        self.assertEqual(bme.get_tstandy(), bme280.TSTANDBY_20)
120
+        self.assertEqual(bme.get_filter(), bme280.FILTER_OFF)
121
+        bme.set_filter(bme280.FILTER_16)
122
+        self.assertEqual(bme.get_filter(), bme280.FILTER_16)
123
+        self.assertMatchSnapshot(mockbus._log)
124
+
125
+    def test_data(self):
126
+        mockbus = setup_mockbus(initial_read={
127
+            0x76: calibration_read() + [0x00] * 8
128
+        })
129
+        bme = bme280.Bme280()
130
+        bme.set_mode(bme280.MODE_FORCED)
131
+        t, p, h = bme.get_data()
132
+        # self.assertEqual(t, 0x00)
133
+        self.assertMatchSnapshot(mockbus._log)

+ 0
- 0
tests/snapshots/__init__.py View File


+ 3052
- 0
tests/snapshots/snap_bme280_test.py
File diff suppressed because it is too large
View File