S allius/pytest (#211)

* - fix pytest setup that can be startet from the rootdir
  - support python venv environment
  - add pytest.ini
  - move common settings from .vscode/settings.json into pytest.ini
  - add missing requirements
  - fix import paths for pytests

* - support python venv environment

* initial version

* - add missing requirements python-dotenv

* fix import paths for pytests

* fix pytest warnings

* initial version

* report 5 slowest test durations

* add more vscode settings for python
This commit is contained in:
Stefan Allius
2024-11-24 22:07:43 +01:00
committed by GitHub
parent 84231c034c
commit 3bada76516
40 changed files with 187 additions and 248 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
__pycache__ __pycache__
.pytest_cache .pytest_cache
.venv/**
bin/** bin/**
mosquitto/** mosquitto/**
homeassistant/** homeassistant/**

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.12.7

15
.vscode/settings.json vendored
View File

@@ -1,10 +1,12 @@
{ {
"python.analysis.extraPaths": [
"app/src",
".venv/lib" ],
"python.testing.pytestArgs": [ "python.testing.pytestArgs": [
"-vv", "-v",
"app",
"--cov=app/src", "--cov=app/src",
"--cov-report=xml", "--cov-report=xml",
"--cov-report=html", "app",
"system_tests" "system_tests"
], ],
"python.testing.unittestEnabled": false, "python.testing.unittestEnabled": false,
@@ -18,5 +20,10 @@
}, },
"files.exclude": { "files.exclude": {
"**/*.pyi": true "**/*.pyi": true
} },
"python.analysis.typeEvaluation.deprecateTypingAliases": true,
"python.autoComplete.extraPaths": [
".venv/lib"
],
"coverage-gutters.coverageBaseDir": "tsun"
} }

View File

@@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.11.1] - 2024-11-20 ## [0.11.1] - 2024-11-20
- fix pytest setup that can be startet from the rootdir
- support python venv environment
- add pytest.ini
- move common settings from .vscode/settings.json into pytest.ini
- add missing requirements
- fix import paths for pytests
- Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.5 to 3.10.11. - Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.5 to 3.10.11.
## [0.11.0] - 2024-10-13 ## [0.11.0] - 2024-10-13

View File

@@ -2,5 +2,6 @@
pytest pytest
pytest-asyncio pytest-asyncio
pytest-cov pytest-cov
python-dotenv
mock mock
coverage coverage

View File

@@ -6,16 +6,10 @@ from asyncio import StreamReader, StreamWriter
from typing import Self from typing import Self
from itertools import count from itertools import count
if __name__ == "app.src.async_stream": from proxy import Proxy
from app.src.proxy import Proxy from byte_fifo import ByteFifo
from app.src.byte_fifo import ByteFifo from async_ifc import AsyncIfc
from app.src.async_ifc import AsyncIfc from infos import Infos
from app.src.infos import Infos
else: # pragma: no cover
from proxy import Proxy
from byte_fifo import ByteFifo
from async_ifc import AsyncIfc
from infos import Infos
import gc import gc

View File

@@ -1,8 +1,4 @@
from messages import hex_dump_str, hex_dump_memory
if __name__ == "app.src.byte_fifo":
from app.src.messages import hex_dump_str, hex_dump_memory
else: # pragma: no cover
from messages import hex_dump_str, hex_dump_memory
class ByteFifo: class ByteFifo:

View File

@@ -3,10 +3,7 @@ import struct
import logging import logging
from typing import Generator from typing import Generator
if __name__ == "app.src.gen3.infos_g3": from infos import Infos, Register
from app.src.infos import Infos, Register
else: # pragma: no cover
from infos import Infos, Register
class RegisterMap: class RegisterMap:

View File

@@ -1,10 +1,7 @@
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter
if __name__ == "app.src.gen3.inverter_g3":
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.gen3.talent import Talent from gen3.talent import Talent
else: # pragma: no cover
from inverter_base import InverterBase
from gen3.talent import Talent
class InverterG3(InverterBase): class InverterG3(InverterBase):

View File

@@ -4,20 +4,12 @@ from zoneinfo import ZoneInfo
from datetime import datetime from datetime import datetime
from tzlocal import get_localzone from tzlocal import get_localzone
if __name__ == "app.src.gen3.talent": from async_ifc import AsyncIfc
from app.src.async_ifc import AsyncIfc from messages import Message, State
from app.src.messages import Message, State from modbus import Modbus
from app.src.modbus import Modbus from config import Config
from app.src.config import Config from gen3.infos_g3 import InfosG3
from app.src.gen3.infos_g3 import InfosG3 from infos import Register
from app.src.infos import Register
else: # pragma: no cover
from async_ifc import AsyncIfc
from messages import Message, State
from modbus import Modbus
from config import Config
from gen3.infos_g3 import InfosG3
from infos import Register
logger = logging.getLogger('msg') logger = logging.getLogger('msg')

View File

@@ -1,10 +1,7 @@
from typing import Generator from typing import Generator
if __name__ == "app.src.gen3plus.infos_g3p": from infos import Infos, Register, ProxyMode, Fmt
from app.src.infos import Infos, Register, ProxyMode, Fmt
else: # pragma: no cover
from infos import Infos, Register, ProxyMode, Fmt
class RegisterMap: class RegisterMap:

View File

@@ -1,13 +1,8 @@
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter
if __name__ == "app.src.gen3plus.inverter_g3p": from inverter_base import InverterBase
from app.src.inverter_base import InverterBase from gen3plus.solarman_v5 import SolarmanV5
from app.src.gen3plus.solarman_v5 import SolarmanV5 from gen3plus.solarman_emu import SolarmanEmu
from app.src.gen3plus.solarman_emu import SolarmanEmu
else: # pragma: no cover
from inverter_base import InverterBase
from gen3plus.solarman_v5 import SolarmanV5
from gen3plus.solarman_emu import SolarmanEmu
class InverterG3P(InverterBase): class InverterG3P(InverterBase):

View File

@@ -1,16 +1,10 @@
import logging import logging
import struct import struct
if __name__ == "app.src.gen3plus.solarman_emu": from async_ifc import AsyncIfc
from app.src.async_ifc import AsyncIfc from gen3plus.solarman_v5 import SolarmanBase
from app.src.gen3plus.solarman_v5 import SolarmanBase from my_timer import Timer
from app.src.my_timer import Timer from infos import Register
from app.src.infos import Register
else: # pragma: no cover
from async_ifc import AsyncIfc
from gen3plus.solarman_v5 import SolarmanBase
from my_timer import Timer
from infos import Register
logger = logging.getLogger('msg') logger = logging.getLogger('msg')

View File

@@ -4,20 +4,12 @@ import time
import asyncio import asyncio
from datetime import datetime from datetime import datetime
if __name__ == "app.src.gen3plus.solarman_v5": from async_ifc import AsyncIfc
from app.src.async_ifc import AsyncIfc from messages import hex_dump_memory, Message, State
from app.src.messages import hex_dump_memory, Message, State from config import Config
from app.src.modbus import Modbus from modbus import Modbus
from app.src.config import Config from gen3plus.infos_g3p import InfosG3P
from app.src.gen3plus.infos_g3p import InfosG3P from infos import Register, Fmt
from app.src.infos import Register, Fmt
else: # pragma: no cover
from async_ifc import AsyncIfc
from messages import hex_dump_memory, Message, State
from config import Config
from modbus import Modbus
from gen3plus.infos_g3p import InfosG3P
from infos import Register, Fmt
logger = logging.getLogger('msg') logger = logging.getLogger('msg')

View File

@@ -7,22 +7,13 @@ import gc
from aiomqtt import MqttCodeError from aiomqtt import MqttCodeError
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter
if __name__ == "app.src.inverter_base": from inverter_ifc import InverterIfc
from app.src.inverter_ifc import InverterIfc from proxy import Proxy
from app.src.proxy import Proxy from async_stream import StreamPtr
from app.src.async_stream import StreamPtr from async_stream import AsyncStreamClient
from app.src.async_stream import AsyncStreamClient from async_stream import AsyncStreamServer
from app.src.async_stream import AsyncStreamServer from config import Config
from app.src.config import Config from infos import Infos
from app.src.infos import Infos
else: # pragma: no cover
from inverter_ifc import InverterIfc
from proxy import Proxy
from async_stream import StreamPtr
from async_stream import AsyncStreamClient
from async_stream import AsyncStreamServer
from config import Config
from infos import Infos
logger_mqtt = logging.getLogger('mqtt') logger_mqtt = logging.getLogger('mqtt')

View File

@@ -2,10 +2,7 @@ from abc import abstractmethod
import logging import logging
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter
if __name__ == "app.src.inverter_ifc": from iter_registry import AbstractIterMeta
from app.src.iter_registry import AbstractIterMeta
else: # pragma: no cover
from iter_registry import AbstractIterMeta
logger_mqtt = logging.getLogger('mqtt') logger_mqtt = logging.getLogger('mqtt')

View File

@@ -3,19 +3,11 @@ import weakref
from typing import Callable from typing import Callable
from enum import Enum from enum import Enum
from async_ifc import AsyncIfc
if __name__ == "app.src.messages": from protocol_ifc import ProtocolIfc
from app.src.async_ifc import AsyncIfc from infos import Infos, Register
from app.src.protocol_ifc import ProtocolIfc from modbus import Modbus
from app.src.infos import Infos, Register from my_timer import Timer
from app.src.modbus import Modbus
from app.src.my_timer import Timer
else: # pragma: no cover
from async_ifc import AsyncIfc
from protocol_ifc import ProtocolIfc
from infos import Infos, Register
from modbus import Modbus
from my_timer import Timer
logger = logging.getLogger('msg') logger = logging.getLogger('msg')

View File

@@ -16,10 +16,7 @@ import logging
import asyncio import asyncio
from typing import Generator, Callable from typing import Generator, Callable
if __name__ == "app.src.modbus": from infos import Register, Fmt
from app.src.infos import Register, Fmt
else: # pragma: no cover
from infos import Register, Fmt
logger = logging.getLogger('data') logger = logging.getLogger('data')

View File

@@ -2,14 +2,9 @@ import logging
import traceback import traceback
import asyncio import asyncio
if __name__ == "app.src.modbus_tcp": from config import Config
from app.src.config import Config from gen3plus.inverter_g3p import InverterG3P
from app.src.gen3plus.inverter_g3p import InverterG3P from infos import Infos
from app.src.infos import Infos
else: # pragma: no cover
from config import Config
from gen3plus.inverter_g3p import InverterG3P
from infos import Infos
logger = logging.getLogger('conn') logger = logging.getLogger('conn')

View File

@@ -2,16 +2,11 @@ import asyncio
import logging import logging
import aiomqtt import aiomqtt
import traceback import traceback
if __name__ == "app.src.mqtt":
from app.src.modbus import Modbus from modbus import Modbus
from app.src.messages import Message from messages import Message
from app.src.config import Config from config import Config
from app.src.singleton import Singleton from singleton import Singleton
else: # pragma: no cover
from modbus import Modbus
from messages import Message
from config import Config
from singleton import Singleton
logger_mqtt = logging.getLogger('mqtt') logger_mqtt = logging.getLogger('mqtt')

View File

@@ -1,11 +1,7 @@
from abc import abstractmethod from abc import abstractmethod
if __name__ == "app.src.protocol_ifc": from async_ifc import AsyncIfc
from app.src.iter_registry import AbstractIterMeta from iter_registry import AbstractIterMeta
from app.src.async_ifc import AsyncIfc
else: # pragma: no cover
from iter_registry import AbstractIterMeta
from async_ifc import AsyncIfc
class ProtocolIfc(metaclass=AbstractIterMeta): class ProtocolIfc(metaclass=AbstractIterMeta):

View File

@@ -2,14 +2,9 @@ import asyncio
import logging import logging
import json import json
if __name__ == "app.src.proxy": from config import Config
from app.src.config import Config from mqtt import Mqtt
from app.src.mqtt import Mqtt from infos import Infos
from app.src.infos import Infos
else: # pragma: no cover
from config import Config
from mqtt import Mqtt
from infos import Infos
logger_mqtt = logging.getLogger('mqtt') logger_mqtt = logging.getLogger('mqtt')

View File

@@ -4,12 +4,13 @@ import asyncio
import gc import gc
import time import time
from app.src.infos import Infos from infos import Infos
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.async_stream import AsyncStreamServer, AsyncStreamClient, StreamPtr from async_stream import AsyncStreamServer, AsyncStreamClient, StreamPtr
from app.src.messages import Message from messages import Message
from app.tests.test_modbus_tcp import FakeReader, FakeWriter
from app.tests.test_inverter_base import config_conn, patch_open_connection from test_modbus_tcp import FakeReader, FakeWriter
from test_inverter_base import config_conn, patch_open_connection
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -541,7 +542,7 @@ async def test_forward_resp():
remote = StreamPtr(None) remote = StreamPtr(None)
cnt = 0 cnt = 0
async def _close_cb(): def _close_cb():
nonlocal cnt, remote, ifc nonlocal cnt, remote, ifc
cnt += 1 cnt += 1
@@ -550,7 +551,7 @@ async def test_forward_resp():
create_remote(remote, TestType.FWD_NO_EXCPT) create_remote(remote, TestType.FWD_NO_EXCPT)
ifc.fwd_add(b'test-forward_msg') ifc.fwd_add(b'test-forward_msg')
await ifc.client_loop('') await ifc.client_loop('')
assert cnt == 0 assert cnt == 1
del ifc del ifc
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -559,7 +560,7 @@ async def test_forward_resp2():
remote = StreamPtr(None) remote = StreamPtr(None)
cnt = 0 cnt = 0
async def _close_cb(): def _close_cb():
nonlocal cnt, remote, ifc nonlocal cnt, remote, ifc
cnt += 1 cnt += 1
@@ -568,5 +569,5 @@ async def test_forward_resp2():
create_remote(remote, TestType.FWD_NO_EXCPT) create_remote(remote, TestType.FWD_NO_EXCPT)
ifc.fwd_add(b'test-forward_msg') ifc.fwd_add(b'test-forward_msg')
await ifc.client_loop('') await ifc.client_loop('')
assert cnt == 0 assert cnt == 1
del ifc del ifc

View File

@@ -1,6 +1,6 @@
# test_with_pytest.py # test_with_pytest.py
from app.src.byte_fifo import ByteFifo from byte_fifo import ByteFifo
def test_fifo(): def test_fifo():
read = ByteFifo() read = ByteFifo()

View File

@@ -1,7 +1,7 @@
# test_with_pytest.py # test_with_pytest.py
import tomllib import tomllib
from schema import SchemaMissingKeyError from schema import SchemaMissingKeyError
from app.src.config import Config from config import Config
class TstConfig(Config): class TstConfig(Config):

View File

@@ -2,8 +2,8 @@
import pytest import pytest
import json, math import json, math
import logging import logging
from app.src.infos import Register, ClrAtMidnight from infos import Register, ClrAtMidnight
from app.src.infos import Infos, Fmt from infos import Infos, Fmt
def test_statistic_counter(): def test_statistic_counter():
i = Infos() i = Infos()

View File

@@ -1,7 +1,7 @@
# test_with_pytest.py # test_with_pytest.py
import pytest, json, math import pytest, json, math
from app.src.infos import Register from infos import Register
from app.src.gen3.infos_g3 import InfosG3, RegisterMap from gen3.infos_g3 import InfosG3, RegisterMap
@pytest.fixture @pytest.fixture
def contr_data_seq(): # Get Time Request message def contr_data_seq(): # Get Time Request message

View File

@@ -1,9 +1,9 @@
# test_with_pytest.py # test_with_pytest.py
import pytest, json, math, random import pytest, json, math, random
from app.src.infos import Register from infos import Register
from app.src.gen3plus.infos_g3p import InfosG3P from gen3plus.infos_g3p import InfosG3P
from app.src.gen3plus.infos_g3p import RegisterMap from gen3plus.infos_g3p import RegisterMap
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def str_test_ip(): def str_test_ip():

View File

@@ -5,14 +5,14 @@ import gc
from mock import patch from mock import patch
from enum import Enum from enum import Enum
from app.src.infos import Infos from infos import Infos
from app.src.config import Config from config import Config
from app.src.gen3.talent import Talent from gen3.talent import Talent
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.singleton import Singleton from singleton import Singleton
from app.src.async_stream import AsyncStream, AsyncStreamClient from async_stream import AsyncStream, AsyncStreamClient
from app.tests.test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname from test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -69,13 +69,13 @@ class FakeWriter():
async def wait_closed(self): async def wait_closed(self):
return return
class TestType(Enum): class MockType(Enum):
RD_TEST_0_BYTES = 1 RD_TEST_0_BYTES = 1
RD_TEST_TIMEOUT = 2 RD_TEST_TIMEOUT = 2
RD_TEST_EXCEPT = 3 RD_TEST_EXCEPT = 3
test = TestType.RD_TEST_0_BYTES test = MockType.RD_TEST_0_BYTES
@pytest.fixture @pytest.fixture
def patch_open_connection(): def patch_open_connection():
@@ -85,9 +85,9 @@ def patch_open_connection():
def new_open(host: str, port: int): def new_open(host: str, port: int):
global test global test
if test == TestType.RD_TEST_TIMEOUT: if test == MockType.RD_TEST_TIMEOUT:
raise ConnectionRefusedError raise ConnectionRefusedError
elif test == TestType.RD_TEST_EXCEPT: elif test == MockType.RD_TEST_EXCEPT:
raise ValueError("Value cannot be negative") # Compliant raise ValueError("Value cannot be negative") # Compliant
return new_conn(None) return new_conn(None)

View File

@@ -5,15 +5,15 @@ import sys,gc
from mock import patch from mock import patch
from enum import Enum from enum import Enum
from app.src.infos import Infos from infos import Infos
from app.src.config import Config from config import Config
from app.src.proxy import Proxy from proxy import Proxy
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.singleton import Singleton from singleton import Singleton
from app.src.gen3.inverter_g3 import InverterG3 from gen3.inverter_g3 import InverterG3
from app.src.async_stream import AsyncStream from async_stream import AsyncStream
from app.tests.test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname from test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -70,13 +70,13 @@ class FakeWriter():
async def wait_closed(self): async def wait_closed(self):
return return
class TestType(Enum): class MockType(Enum):
RD_TEST_0_BYTES = 1 RD_TEST_0_BYTES = 1
RD_TEST_TIMEOUT = 2 RD_TEST_TIMEOUT = 2
RD_TEST_EXCEPT = 3 RD_TEST_EXCEPT = 3
test = TestType.RD_TEST_0_BYTES test = MockType.RD_TEST_0_BYTES
@pytest.fixture @pytest.fixture
def patch_open_connection(): def patch_open_connection():
@@ -86,9 +86,9 @@ def patch_open_connection():
def new_open(host: str, port: int): def new_open(host: str, port: int):
global test global test
if test == TestType.RD_TEST_TIMEOUT: if test == MockType.RD_TEST_TIMEOUT:
raise ConnectionRefusedError raise ConnectionRefusedError
elif test == TestType.RD_TEST_EXCEPT: elif test == MockType.RD_TEST_EXCEPT:
raise ValueError("Value cannot be negative") # Compliant raise ValueError("Value cannot be negative") # Compliant
return new_conn(None) return new_conn(None)
@@ -144,14 +144,14 @@ async def test_remote_except(config_conn, patch_open_connection):
assert asyncio.get_running_loop() assert asyncio.get_running_loop()
global test global test
test = TestType.RD_TEST_TIMEOUT test = MockType.RD_TEST_TIMEOUT
with InverterG3(FakeReader(), FakeWriter()) as inverter: with InverterG3(FakeReader(), FakeWriter()) as inverter:
await inverter.create_remote() await inverter.create_remote()
await asyncio.sleep(0) await asyncio.sleep(0)
assert inverter.remote.stream==None assert inverter.remote.stream==None
test = TestType.RD_TEST_EXCEPT test = MockType.RD_TEST_EXCEPT
await inverter.create_remote() await inverter.create_remote()
await asyncio.sleep(0) await asyncio.sleep(0)
assert inverter.remote.stream==None assert inverter.remote.stream==None

View File

@@ -4,14 +4,14 @@ import asyncio
from mock import patch from mock import patch
from enum import Enum from enum import Enum
from app.src.infos import Infos from infos import Infos
from app.src.config import Config from config import Config
from app.src.proxy import Proxy from proxy import Proxy
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.singleton import Singleton from singleton import Singleton
from app.src.gen3plus.inverter_g3p import InverterG3P from gen3plus.inverter_g3p import InverterG3P
from app.tests.test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname from test_modbus_tcp import patch_mqtt_err, patch_mqtt_except, test_port, test_hostname
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -69,13 +69,13 @@ class FakeWriter():
async def wait_closed(self): async def wait_closed(self):
return return
class TestType(Enum): class MockType(Enum):
RD_TEST_0_BYTES = 1 RD_TEST_0_BYTES = 1
RD_TEST_TIMEOUT = 2 RD_TEST_TIMEOUT = 2
RD_TEST_EXCEPT = 3 RD_TEST_EXCEPT = 3
test = TestType.RD_TEST_0_BYTES test = MockType.RD_TEST_0_BYTES
@pytest.fixture @pytest.fixture
def patch_open_connection(): def patch_open_connection():
@@ -85,9 +85,9 @@ def patch_open_connection():
def new_open(host: str, port: int): def new_open(host: str, port: int):
global test global test
if test == TestType.RD_TEST_TIMEOUT: if test == MockType.RD_TEST_TIMEOUT:
raise ConnectionRefusedError raise ConnectionRefusedError
elif test == TestType.RD_TEST_EXCEPT: elif test == MockType.RD_TEST_EXCEPT:
raise ValueError("Value cannot be negative") # Compliant raise ValueError("Value cannot be negative") # Compliant
return new_conn(None) return new_conn(None)
@@ -121,14 +121,14 @@ async def test_remote_except(config_conn, patch_open_connection):
assert asyncio.get_running_loop() assert asyncio.get_running_loop()
global test global test
test = TestType.RD_TEST_TIMEOUT test = MockType.RD_TEST_TIMEOUT
with InverterG3P(FakeReader(), FakeWriter(), client_mode=False) as inverter: with InverterG3P(FakeReader(), FakeWriter(), client_mode=False) as inverter:
await inverter.create_remote() await inverter.create_remote()
await asyncio.sleep(0) await asyncio.sleep(0)
assert inverter.remote.stream==None assert inverter.remote.stream==None
test = TestType.RD_TEST_EXCEPT test = MockType.RD_TEST_EXCEPT
await inverter.create_remote() await inverter.create_remote()
await asyncio.sleep(0) await asyncio.sleep(0)
assert inverter.remote.stream==None assert inverter.remote.stream==None

View File

@@ -1,8 +1,8 @@
# test_with_pytest.py # test_with_pytest.py
import pytest import pytest
import asyncio import asyncio
from app.src.modbus import Modbus from modbus import Modbus
from app.src.infos import Infos, Register from infos import Infos, Register
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

View File

@@ -5,14 +5,14 @@ from aiomqtt import MqttCodeError
from mock import patch from mock import patch
from enum import Enum from enum import Enum
from app.src.singleton import Singleton from singleton import Singleton
from app.src.config import Config from config import Config
from app.src.infos import Infos from infos import Infos
from app.src.mqtt import Mqtt from mqtt import Mqtt
from app.src.inverter_base import InverterBase from inverter_base import InverterBase
from app.src.messages import Message, State from messages import Message, State
from app.src.proxy import Proxy from proxy import Proxy
from app.src.modbus_tcp import ModbusConn, ModbusTcp from modbus_tcp import ModbusConn, ModbusTcp
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

View File

@@ -5,12 +5,12 @@ import aiomqtt
import logging import logging
from mock import patch, Mock from mock import patch, Mock
from app.src.async_stream import AsyncIfcImpl from async_stream import AsyncIfcImpl
from app.src.singleton import Singleton from singleton import Singleton
from app.src.mqtt import Mqtt from mqtt import Mqtt
from app.src.modbus import Modbus from modbus import Modbus
from app.src.gen3plus.solarman_v5 import SolarmanV5 from gen3plus.solarman_v5 import SolarmanV5
from app.src.config import Config from config import Config
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

View File

@@ -5,11 +5,11 @@ import aiomqtt
import logging import logging
from mock import patch, Mock from mock import patch, Mock
from app.src.singleton import Singleton from singleton import Singleton
from app.src.proxy import Proxy from proxy import Proxy
from app.src.mqtt import Mqtt from mqtt import Mqtt
from app.src.gen3plus.solarman_v5 import SolarmanV5 from gen3plus.solarman_v5 import SolarmanV5
from app.src.config import Config from config import Config
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

View File

@@ -1,16 +1,16 @@
# test_with_pytest.py # test_with_pytest.py
import pytest import pytest
from app.src.singleton import Singleton from singleton import Singleton
class Test(metaclass=Singleton): class Example(metaclass=Singleton):
def __init__(self): def __init__(self):
pass # is a dummy test class pass # is a dummy test class
def test_singleton_metaclass(): def test_singleton_metaclass():
Singleton._instances.clear() Singleton._instances.clear()
a = Test() a = Example()
assert 1 == len(Singleton._instances) assert 1 == len(Singleton._instances)
b = Test() b = Example()
assert 1 == len(Singleton._instances) assert 1 == len(Singleton._instances)
assert a is b assert a is b
del a del a

View File

@@ -5,12 +5,12 @@ import asyncio
import logging import logging
import random import random
from math import isclose from math import isclose
from app.src.async_stream import AsyncIfcImpl, StreamPtr from async_stream import AsyncIfcImpl, StreamPtr
from app.src.gen3plus.solarman_v5 import SolarmanV5, SolarmanBase from gen3plus.solarman_v5 import SolarmanV5, SolarmanBase
from app.src.config import Config from config import Config
from app.src.infos import Infos, Register from infos import Infos, Register
from app.src.modbus import Modbus from modbus import Modbus
from app.src.messages import State, Message from messages import State, Message
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

View File

@@ -1,11 +1,13 @@
import pytest import pytest
import asyncio import asyncio
from app.src.async_stream import AsyncIfcImpl, StreamPtr
from app.src.gen3plus.solarman_v5 import SolarmanV5, SolarmanBase from async_stream import AsyncIfcImpl, StreamPtr
from app.src.gen3plus.solarman_emu import SolarmanEmu from gen3plus.solarman_v5 import SolarmanV5, SolarmanBase
from app.src.infos import Infos, Register from gen3plus.solarman_emu import SolarmanEmu
from app.tests.test_solarman import FakeIfc, MemoryStream, get_sn_int, get_sn, correct_checksum, config_tsun_inv1, msg_modbus_rsp from infos import Infos, Register
from app.tests.test_infos_g3p import str_test_ip, bytes_test_ip
from test_solarman import FakeIfc, MemoryStream, get_sn_int, get_sn, correct_checksum, config_tsun_inv1, msg_modbus_rsp
from test_infos_g3p import str_test_ip, bytes_test_ip
timestamp = 0x3224c8bc timestamp = 0x3224c8bc

View File

@@ -1,12 +1,12 @@
# test_with_pytest.py # test_with_pytest.py
import pytest, logging, asyncio import pytest, logging, asyncio
from math import isclose from math import isclose
from app.src.async_stream import AsyncIfcImpl, StreamPtr from async_stream import AsyncIfcImpl, StreamPtr
from app.src.gen3.talent import Talent, Control from gen3.talent import Talent, Control
from app.src.config import Config from config import Config
from app.src.infos import Infos, Register from infos import Infos, Register
from app.src.modbus import Modbus from modbus import Modbus
from app.src.messages import State from messages import State
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)

8
pytest.ini Normal file
View File

@@ -0,0 +1,8 @@
# pytest.ini or .pytest.ini
[pytest]
minversion = 8.0
addopts = -ra -q --durations=5
pythonpath = app/src
testpaths = app/tests
asyncio_default_fixture_loop_scope = function
asyncio_mode = strict