Rewrite demo unittest tests to pytest style test functions (#41845)

This commit is contained in:
CurrentThread 2020-10-19 23:29:44 +02:00 committed by GitHub
parent 7e3aa6ddce
commit e129ea4db7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 258 additions and 261 deletions

View File

@ -1,5 +1,4 @@
"""The tests for the demo platform.""" """The tests for the demo platform."""
import unittest
import pytest import pytest
@ -14,15 +13,11 @@ from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_UNIT_OF_MEASUREMENT,
LENGTH_KILOMETERS, LENGTH_KILOMETERS,
) )
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.async_mock import patch from tests.async_mock import patch
from tests.common import ( from tests.common import assert_setup_component, async_fire_time_changed
assert_setup_component,
fire_time_changed,
get_test_home_assistant,
)
CONFIG = {geo_location.DOMAIN: [{"platform": "demo"}]} CONFIG = {geo_location.DOMAIN: [{"platform": "demo"}]}
@ -33,28 +28,20 @@ def mock_legacy_time(legacy_patchable_time):
yield yield
class TestDemoPlatform(unittest.TestCase): async def test_setup_platform(hass):
"""Test the demo platform."""
def setUp(self):
"""Initialize values for this testcase class."""
self.hass = get_test_home_assistant()
self.addCleanup(self.hass.stop)
def test_setup_platform(self):
"""Test setup of demo platform via configuration.""" """Test setup of demo platform via configuration."""
utcnow = dt_util.utcnow() utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update. # Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow): with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
with assert_setup_component(1, geo_location.DOMAIN): with assert_setup_component(1, geo_location.DOMAIN):
assert setup_component(self.hass, geo_location.DOMAIN, CONFIG) assert await async_setup_component(hass, geo_location.DOMAIN, CONFIG)
self.hass.block_till_done() await hass.async_block_till_done()
# In this test, one zone and geolocation entities have been # In this test, one zone and geolocation entities have been
# generated. # generated.
all_states = [ all_states = [
self.hass.states.get(entity_id) hass.states.get(entity_id)
for entity_id in self.hass.states.entity_ids(geo_location.DOMAIN) for entity_id in hass.states.async_entity_ids(geo_location.DOMAIN)
] ]
assert len(all_states) == NUMBER_OF_DEMO_DEVICES assert len(all_states) == NUMBER_OF_DEMO_DEVICES
@ -63,24 +50,18 @@ class TestDemoPlatform(unittest.TestCase):
if state.domain != geo_location.DOMAIN: if state.domain != geo_location.DOMAIN:
# ignore home zone state # ignore home zone state
continue continue
assert ( assert abs(state.attributes[ATTR_LATITUDE] - hass.config.latitude) < 1.0
abs(state.attributes[ATTR_LATITUDE] - self.hass.config.latitude) assert abs(state.attributes[ATTR_LONGITUDE] - hass.config.longitude) < 1.0
< 1.0
)
assert (
abs(state.attributes[ATTR_LONGITUDE] - self.hass.config.longitude)
< 1.0
)
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == LENGTH_KILOMETERS assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == LENGTH_KILOMETERS
# Update (replaces 1 device). # Update (replaces 1 device).
fire_time_changed(self.hass, utcnow + DEFAULT_UPDATE_INTERVAL) async_fire_time_changed(hass, utcnow + DEFAULT_UPDATE_INTERVAL)
self.hass.block_till_done() await hass.async_block_till_done()
# Get all states again, ensure that the number of states is still # Get all states again, ensure that the number of states is still
# the same, but the lists are different. # the same, but the lists are different.
all_states_updated = [ all_states_updated = [
self.hass.states.get(entity_id) hass.states.get(entity_id)
for entity_id in self.hass.states.entity_ids(geo_location.DOMAIN) for entity_id in hass.states.async_entity_ids(geo_location.DOMAIN)
] ]
assert len(all_states_updated) == NUMBER_OF_DEMO_DEVICES assert len(all_states_updated) == NUMBER_OF_DEMO_DEVICES
assert all_states != all_states_updated assert all_states != all_states_updated

View File

@ -1,5 +1,6 @@
"""The tests for the notify demo platform.""" """The tests for the notify demo platform."""
import unittest
import logging
import pytest import pytest
import voluptuous as vol import voluptuous as vol
@ -8,185 +9,194 @@ import homeassistant.components.demo.notify as demo
import homeassistant.components.notify as notify import homeassistant.components.notify as notify
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from tests.async_mock import patch from tests.async_mock import patch
from tests.common import assert_setup_component, get_test_home_assistant from tests.common import assert_setup_component
from tests.components.notify import common
CONFIG = {notify.DOMAIN: {"platform": "demo"}} CONFIG = {notify.DOMAIN: {"platform": "demo"}}
class TestNotifyDemo(unittest.TestCase): @pytest.fixture
"""Test the demo notify.""" def events(hass):
"""Fixture that catches notify events."""
events = []
hass.bus.async_listen(demo.EVENT_NOTIFY, callback(lambda e: events.append(e)))
yield events
def setUp(self): # pylint: disable=invalid-name
"""Set up things to be run when tests are started.""" @pytest.fixture
self.hass = get_test_home_assistant() def calls():
self.events = [] """Fixture to calls."""
self.calls = [] return []
@pytest.fixture
def record_calls(calls):
"""Fixture to record calls."""
@callback @callback
def record_event(event): def record_calls(*args):
"""Record event to send notification.""" """Record calls."""
self.events.append(event) calls.append(args)
self.hass.bus.listen(demo.EVENT_NOTIFY, record_event) return record_calls
self.addCleanup(self.tear_down_cleanup)
def tear_down_cleanup(self):
"""Stop down everything that was started."""
self.hass.stop()
def _setup_notify(self): @pytest.fixture(name="mock_demo_notify")
with assert_setup_component(1, notify.DOMAIN) as config: def mock_demo_notify_fixture():
assert setup_component(self.hass, notify.DOMAIN, CONFIG) """Mock demo notify service."""
assert config[notify.DOMAIN] with patch("homeassistant.components.demo.notify.get_service", autospec=True) as ns:
self.hass.block_till_done() yield ns
def test_setup(self):
async def setup_notify(hass):
"""Test setup.""" """Test setup."""
self._setup_notify() with assert_setup_component(1, notify.DOMAIN) as config:
assert await async_setup_component(hass, notify.DOMAIN, CONFIG)
assert config[notify.DOMAIN]
await hass.async_block_till_done()
@patch("homeassistant.components.demo.notify.get_service", autospec=True)
def test_no_notify_service(self, mock_demo_get_service): async def test_no_notify_service(hass, mock_demo_notify, caplog):
"""Test missing platform notify service instance.""" """Test missing platform notify service instance."""
mock_demo_get_service.return_value = None caplog.set_level(logging.ERROR)
with self.assertLogs( mock_demo_notify.return_value = None
"homeassistant.components.notify", level="ERROR" await setup_notify(hass)
) as log_handle: await hass.async_block_till_done()
self._setup_notify() assert mock_demo_notify.called
self.hass.block_till_done() assert "Failed to initialize notification service demo" in caplog.text
assert mock_demo_get_service.called
assert log_handle.output == [
"ERROR:homeassistant.components.notify:"
"Failed to initialize notification service demo"
]
@patch("homeassistant.components.demo.notify.get_service", autospec=True)
def test_discover_notify(self, mock_demo_get_service): async def test_discover_notify(hass, mock_demo_notify):
"""Test discovery of notify demo platform.""" """Test discovery of notify demo platform."""
assert notify.DOMAIN not in self.hass.config.components assert notify.DOMAIN not in hass.config.components
mock_demo_notify.return_value = None
discovery.load_platform( discovery.load_platform(
self.hass, "notify", "demo", {"test_key": "test_val"}, {"notify": {}} hass, "notify", "demo", {"test_key": "test_val"}, {"notify": {}}
) )
self.hass.block_till_done() await hass.async_block_till_done()
assert notify.DOMAIN in self.hass.config.components assert notify.DOMAIN in hass.config.components
assert mock_demo_get_service.called assert mock_demo_notify.called
assert mock_demo_get_service.mock_calls[0][1] == ( assert mock_demo_notify.mock_calls[0][1] == (
self.hass, hass,
{}, {},
{"test_key": "test_val"}, {"test_key": "test_val"},
) )
@callback
def record_calls(self, *args):
"""Record calls."""
self.calls.append(args)
def test_sending_none_message(self): async def test_sending_none_message(hass, events):
"""Test send with None as message.""" """Test send with None as message."""
self._setup_notify() await setup_notify(hass)
with pytest.raises(vol.Invalid): with pytest.raises(vol.Invalid):
common.send_message(self.hass, None) await hass.services.async_call(
self.hass.block_till_done() notify.DOMAIN, notify.SERVICE_NOTIFY, {notify.ATTR_MESSAGE: None}
assert len(self.events) == 0
def test_sending_templated_message(self):
"""Send a templated message."""
self._setup_notify()
self.hass.states.set("sensor.temperature", 10)
common.send_message(
self.hass,
"{{ states.sensor.temperature.state }}",
"{{ states.sensor.temperature.name }}",
) )
self.hass.block_till_done() await hass.async_block_till_done()
last_event = self.events[-1] assert len(events) == 0
async def test_sending_templated_message(hass, events):
"""Send a templated message."""
await setup_notify(hass)
hass.states.async_set("sensor.temperature", 10)
data = {
notify.ATTR_MESSAGE: "{{states.sensor.temperature.state}}",
notify.ATTR_TITLE: "{{ states.sensor.temperature.name }}",
}
await hass.services.async_call(notify.DOMAIN, notify.SERVICE_NOTIFY, data)
await hass.async_block_till_done()
last_event = events[-1]
assert last_event.data[notify.ATTR_TITLE] == "temperature" assert last_event.data[notify.ATTR_TITLE] == "temperature"
assert last_event.data[notify.ATTR_MESSAGE] == 10 assert last_event.data[notify.ATTR_MESSAGE] == 10
def test_method_forwards_correct_data(self):
async def test_method_forwards_correct_data(hass, events):
"""Test that all data from the service gets forwarded to service.""" """Test that all data from the service gets forwarded to service."""
self._setup_notify() await setup_notify(hass)
common.send_message(self.hass, "my message", "my title", {"hello": "world"}) data = {
self.hass.block_till_done() notify.ATTR_MESSAGE: "my message",
assert len(self.events) == 1 notify.ATTR_TITLE: "my title",
data = self.events[0].data notify.ATTR_DATA: {"hello": "world"},
}
await hass.services.async_call(notify.DOMAIN, notify.SERVICE_NOTIFY, data)
await hass.async_block_till_done()
assert len(events) == 1
data = events[0].data
assert { assert {
"message": "my message", "message": "my message",
"title": "my title", "title": "my title",
"data": {"hello": "world"}, "data": {"hello": "world"},
} == data } == data
def test_calling_notify_from_script_loaded_from_yaml_without_title(self):
async def test_calling_notify_from_script_loaded_from_yaml_without_title(hass, events):
"""Test if we can call a notify from a script.""" """Test if we can call a notify from a script."""
self._setup_notify() await setup_notify(hass)
step = { step = {
"service": "notify.notify", "service": "notify.notify",
"data": { "data": {
"data": { "data": {"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}}
"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}
}
}, },
"data_template": {"message": "Test 123 {{ 2 + 2 }}\n"}, "data_template": {"message": "Test 123 {{ 2 + 2 }}\n"},
} }
setup_component(self.hass, "script", {"script": {"test": {"sequence": step}}}) await async_setup_component(
self.hass.services.call("script", "test") hass, "script", {"script": {"test": {"sequence": step}}}
self.hass.block_till_done() )
assert len(self.events) == 1 await hass.services.async_call("script", "test")
await hass.async_block_till_done()
assert len(events) == 1
assert { assert {
"message": "Test 123 4", "message": "Test 123 4",
"data": { "data": {"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}},
"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"} } == events[0].data
},
} == self.events[0].data
def test_calling_notify_from_script_loaded_from_yaml_with_title(self):
async def test_calling_notify_from_script_loaded_from_yaml_with_title(hass, events):
"""Test if we can call a notify from a script.""" """Test if we can call a notify from a script."""
self._setup_notify() await setup_notify(hass)
step = { step = {
"service": "notify.notify", "service": "notify.notify",
"data": { "data": {
"data": { "data": {"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}}
"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}
}
}, },
"data_template": {"message": "Test 123 {{ 2 + 2 }}\n", "title": "Test"}, "data_template": {"message": "Test 123 {{ 2 + 2 }}\n", "title": "Test"},
} }
setup_component(self.hass, "script", {"script": {"test": {"sequence": step}}}) await async_setup_component(
self.hass.services.call("script", "test") hass, "script", {"script": {"test": {"sequence": step}}}
self.hass.block_till_done() )
assert len(self.events) == 1 await hass.services.async_call("script", "test")
await hass.async_block_till_done()
assert len(events) == 1
assert { assert {
"message": "Test 123 4", "message": "Test 123 4",
"title": "Test", "title": "Test",
"data": { "data": {"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"}},
"push": {"sound": "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav"} } == events[0].data
},
} == self.events[0].data
def test_targets_are_services(self):
async def test_targets_are_services(hass):
"""Test that all targets are exposed as individual services.""" """Test that all targets are exposed as individual services."""
self._setup_notify() await setup_notify(hass)
assert self.hass.services.has_service("notify", "demo") is not None assert hass.services.has_service("notify", "demo") is not None
service = "demo_test_target_name" service = "demo_test_target_name"
assert self.hass.services.has_service("notify", service) is not None assert hass.services.has_service("notify", service) is not None
def test_messages_to_targets_route(self):
async def test_messages_to_targets_route(hass, calls, record_calls):
"""Test message routing to specific target services.""" """Test message routing to specific target services."""
self._setup_notify() await setup_notify(hass)
self.hass.bus.listen_once("notify", self.record_calls) hass.bus.async_listen_once("notify", record_calls)
self.hass.services.call( await hass.services.async_call(
"notify", "notify",
"demo_test_target_name", "demo_test_target_name",
{"message": "my message", "title": "my title", "data": {"hello": "world"}}, {"message": "my message", "title": "my title", "data": {"hello": "world"}},
) )
self.hass.block_till_done() await hass.async_block_till_done()
data = self.calls[0][0].data data = calls[0][0].data
assert { assert {
"message": "my message", "message": "my message",

View File

@ -1,55 +1,61 @@
"""The tests for the demo remote component.""" """The tests for the demo remote component."""
# pylint: disable=protected-access import pytest
import unittest
import homeassistant.components.remote as remote import homeassistant.components.remote as remote
from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.components.remote import ATTR_COMMAND
from homeassistant.setup import setup_component from homeassistant.const import (
ATTR_ENTITY_ID,
from tests.common import get_test_home_assistant SERVICE_TURN_OFF,
from tests.components.remote import common SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
)
from homeassistant.setup import async_setup_component
ENTITY_ID = "remote.remote_one" ENTITY_ID = "remote.remote_one"
SERVICE_SEND_COMMAND = "send_command"
class TestDemoRemote(unittest.TestCase): @pytest.fixture(autouse=True)
"""Test the demo remote.""" async def setup_component(hass):
"""Initialize components."""
# pylint: disable=invalid-name assert await async_setup_component(
def setUp(self): hass, remote.DOMAIN, {"remote": {"platform": "demo"}}
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
assert setup_component(
self.hass, remote.DOMAIN, {"remote": {"platform": "demo"}}
) )
self.hass.block_till_done() await hass.async_block_till_done()
self.addCleanup(self.tear_down_cleanup)
def tear_down_cleanup(self): async def test_methods(hass):
"""Stop down everything that was started."""
self.hass.stop()
def test_methods(self):
"""Test if services call the entity methods as expected.""" """Test if services call the entity methods as expected."""
common.turn_on(self.hass, entity_id=ENTITY_ID) await hass.services.async_call(
self.hass.block_till_done() remote.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}
state = self.hass.states.get(ENTITY_ID) )
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state.state == STATE_ON assert state.state == STATE_ON
common.turn_off(self.hass, entity_id=ENTITY_ID) await hass.services.async_call(
self.hass.block_till_done() remote.DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}
state = self.hass.states.get(ENTITY_ID) )
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state.state == STATE_OFF assert state.state == STATE_OFF
common.turn_on(self.hass, entity_id=ENTITY_ID) await hass.services.async_call(
self.hass.block_till_done() remote.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}
state = self.hass.states.get(ENTITY_ID) )
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state.state == STATE_ON assert state.state == STATE_ON
common.send_command(self.hass, "test", entity_id=ENTITY_ID) data = {
self.hass.block_till_done() ATTR_ENTITY_ID: ENTITY_ID,
state = self.hass.states.get(ENTITY_ID) ATTR_COMMAND: ["test"],
}
await hass.services.async_call(remote.DOMAIN, SERVICE_SEND_COMMAND, data)
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state.attributes == { assert state.attributes == {
"friendly_name": "Remote One", "friendly_name": "Remote One",
"last_command_sent": "test", "last_command_sent": "test",