blob: af03918cd6aa1140e33f75bcb8f75dc13e7312f2 [file] [log] [blame]
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This is the sample code of a board specific test.
Description
-----------
This is a sample test code to demostrate how to write a board-specific test.
A board specific test should be put in the board overlay. For example, assuming
the overlay is located at
``~/trunk/src/private-overlays/overlay-${BOARD}-private``, then you have to
create the factory-board package and put files under relative path
``chromeos-base/factory-board/files/py/pytests/``.
To avoid file name conflict, please name the python script as "${BOARD}_xxx.py".
For example, if you are implementing your own touchscreen test for board ABC, a
reasonable file name would be: ``abc_touchscreen.py``.
Test Procedure
--------------
This is only a sample code to demonstrate how to write a board-specific test.
Dependency
----------
None.
Examples
--------
To run this sample code with default arguments, add this in test list::
{
"pytest_name": "sample_customized_test",
"args": {
"foo": 1
}
}
"""
import logging
import unittest
import factory_common # pylint: disable=unused-import
from cros.factory.device import device_utils
from cros.factory.testlog import testlog
from cros.factory.utils import arg_utils
from cros.factory.utils import type_utils
class SampleCustomizedTest(unittest.TestCase):
"""Example of how to write a pytest.
The pytest must inherit `unittest.TestCase`, and implement `runTest` function.
The `runTest` function is similar to the main function of the test. When the
test starts, this function will be called. You can also implement `setUp` and
`tearDown` functions to make sure something is done before / after the test,
no matter what.
"""
ARGS = [
arg_utils.Arg(
'foo', int, help='foo can only be int, not optional'),
arg_utils.Arg(
'bar', str, help='bar is optional, default to None',
default=None),
arg_utils.Arg(
'baz', str, help='baz is optional, default to "BAZ"',
default="BAZ"),
]
"""Arguments of this pytest.
Arguments of a pytest is defined by class variable "ARGS", which must be a
list of `cros.factory.utils.arg_utils.Arg` object. You can specify the value
of each argument in the test list:
{
"pytest_name": "sample_customized_test",
"args": {
"foo": 123,
"bar": "value of bar"
}
}
The value for argument "baz" is not set in the above example, so it will use
default value "BAZ".
"""
def setUp(self):
"""Setup function."""
self.dut = device_utils.CreateDUTInterface()
# from now on, you can use `self.dut` to control stuff on DUT
# for example, create a temporary folder on DUT
self.temp_dir = self.dut.temp.mktemp(is_dir=True)
# Group checker for Testlog.
self.group_checker = testlog.GroupParam(
'audio', ['audio_quality', 'audio_frequency'])
testlog.UpdateParam('audio_frequency',
param_type=testlog.PARAM_TYPE.argument)
testlog.UpdateParam(
name='audio_quality',
description='quality of audio device on different frequency',
value_unit='quality')
testlog.UpdateParam(
name='audio_frequency',
value_unit='Hz')
def tearDown(self):
"""Tear down function (for clean up)."""
# remove the folder we created, and everything inside that folder.
self.dut.CheckCall(['rm', '-rf', self.temp_dir])
def runTest(self):
"""Main function of the test. Implement test logic in this function."""
# for example, measure some value on DUT.
photo_path = self.TakePhoto()
# when you use logging, the message will be logged by testlog automatically.
logging.info('Image captured, attaching to testlog...')
# attach the file to the testlog
testlog.AttachFile(
path=photo_path, mime_type='image/jpeg', name='front_camera.jpeg',
description='image captured by the front camera for quality test.')
quality = self.ComputePhotoQuality(photo_path)
# check and log the value, note that testlog will NOT fail the test for you,
# you have to raise an exception by yourself.
testlog.UpdateParam(
name='photo_quality',
description='Quality of the photo')
if not testlog.CheckNumericParam(
name='photo_quality',
value=quality,
min=0.9, max=1.0):
raise type_utils.TestFailure('The camera is not qualified')
failed = False
for freq in xrange(1000, 4000, 50):
quality = self.MeasureAudioQuality(freq)
# you can also measure and log a series of values
with self.group_checker:
if not testlog.CheckNumericParam('audio_quality', quality, min=0.8):
failed = True
testlog.LogParam('audio_frequency', freq)
if failed:
raise type_utils.TestFailure('The audio device is not qualified')
def TakePhoto(self):
raise NotImplementedError
def ComputePhotoQuality(self, photo_path):
raise NotImplementedError
def MeasureAudioQuality(self, freq):
raise NotImplementedError