* add test level support * update develop doc Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/9021354master
@@ -34,13 +34,62 @@ make linter | |||
``` | |||
## 2. Test | |||
### 2.1 Unit test | |||
### 2.1 Test level | |||
There are mainly three test levels: | |||
* level 0: tests for basic interface and function of framework, such as `tests/trainers/test_trainer_base.py` | |||
* level 1: important functional test which test end2end workflow, such as `tests/pipelines/test_image_matting.py` | |||
* level 2: scenario tests for all the implemented modules such as model, pipeline in different algorithm filed. | |||
Default test level is 0, which will only run those cases of level 0, you can set test level | |||
via environment variable `TEST_LEVEL`. For more details, you can refer to [test-doc](https://alidocs.dingtalk.com/i/nodes/mdvQnONayjBJKLXy1Bp38PY2MeXzp5o0?dontjump=true&nav=spaces&navQuery=spaceId%3Dnb9XJNlZxbgrOXyA) | |||
```bash | |||
# run all tests | |||
TEST_LEVEL=2 make test | |||
# run important functional tests | |||
TEST_LEVEL=1 make test | |||
# run core UT and basic functional tests | |||
make test | |||
``` | |||
### 2.2 Test data | |||
TODO | |||
When writing test cases, you should assign a test level for your test case using | |||
following code. If left default, the test level will be 0, it will run in each | |||
test stage. | |||
File test_module.py | |||
```python | |||
from modelscope.utils.test_utils import test_level | |||
class ImageCartoonTest(unittest.TestCase): | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_by_direct_model_download(self): | |||
pass | |||
``` | |||
### 2.2 Run tests | |||
1. Run your own single test case to test your self-implemented function. You can run your | |||
test file directly, if it fails to run, pls check if variable `TEST_LEVEL` | |||
exists in the environment and unset it. | |||
```bash | |||
python tests/path/to/your_test.py | |||
``` | |||
2. Remember to run core tests in local environment before start a codereview, by default it will | |||
only run test cases with level 0. | |||
```bash | |||
make tests | |||
``` | |||
3. After you start a code review, ci tests will be triggered which will run test cases with level 1 | |||
4. Daily regression tests will run all cases at 0 am each day using master branch. | |||
## Code Review | |||
@@ -0,0 +1,20 @@ | |||
#!/usr/bin/env python | |||
# Copyright (c) Alibaba, Inc. and its affiliates. | |||
import os | |||
TEST_LEVEL = 2 | |||
TEST_LEVEL_STR = 'TEST_LEVEL' | |||
def test_level(): | |||
global TEST_LEVEL | |||
if TEST_LEVEL_STR in os.environ: | |||
TEST_LEVEL = int(os.environ[TEST_LEVEL_STR]) | |||
return TEST_LEVEL | |||
def set_test_level(level: int): | |||
global TEST_LEVEL | |||
TEST_LEVEL = level |
@@ -7,6 +7,7 @@ import unittest | |||
from modelscope.fileio import File | |||
from modelscope.pipelines import pipeline | |||
from modelscope.utils.constant import Tasks | |||
from modelscope.utils.test_utils import test_level | |||
class ImageCaptionTest(unittest.TestCase): | |||
@@ -11,6 +11,7 @@ from modelscope.pipelines import pipeline | |||
from modelscope.pydatasets import PyDataset | |||
from modelscope.utils.constant import ModelFile, Tasks | |||
from modelscope.utils.hub import get_model_cache_dir | |||
from modelscope.utils.test_utils import test_level | |||
class ImageMattingTest(unittest.TestCase): | |||
@@ -38,6 +39,7 @@ class ImageMattingTest(unittest.TestCase): | |||
) | |||
cv2.imwrite('result.png', result['output_png']) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_dataset(self): | |||
input_location = [ | |||
'http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/test/maas/image_matting/test.png' | |||
@@ -52,6 +54,7 @@ class ImageMattingTest(unittest.TestCase): | |||
cv2.imwrite('result.png', next(result)['output_png']) | |||
print(f'Output written to {osp.abspath("result.png")}') | |||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level') | |||
def test_run_modelhub(self): | |||
img_matting = pipeline(Tasks.image_matting, model=self.model_id) | |||
@@ -61,6 +64,7 @@ class ImageMattingTest(unittest.TestCase): | |||
cv2.imwrite('result.png', result['output_png']) | |||
print(f'Output written to {osp.abspath("result.png")}') | |||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level') | |||
def test_run_modelhub_default_model(self): | |||
img_matting = pipeline(Tasks.image_matting) | |||
@@ -8,6 +8,7 @@ import cv2 | |||
from modelscope.pipelines import pipeline | |||
from modelscope.pipelines.base import Pipeline | |||
from modelscope.utils.constant import Tasks | |||
from modelscope.utils.test_utils import test_level | |||
class ImageCartoonTest(unittest.TestCase): | |||
@@ -36,10 +37,12 @@ class ImageCartoonTest(unittest.TestCase): | |||
img_cartoon = pipeline(Tasks.image_generation, model=model_dir) | |||
self.pipeline_inference(img_cartoon, self.test_image) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_modelhub(self): | |||
img_cartoon = pipeline(Tasks.image_generation, model=self.model_id) | |||
self.pipeline_inference(img_cartoon, self.test_image) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_modelhub_default_model(self): | |||
img_cartoon = pipeline(Tasks.image_generation) | |||
self.pipeline_inference(img_cartoon, self.test_image) | |||
@@ -12,6 +12,7 @@ from modelscope.preprocessors import SequenceClassificationPreprocessor | |||
from modelscope.pydatasets import PyDataset | |||
from modelscope.utils.constant import Hubs, Tasks | |||
from modelscope.utils.hub import get_model_cache_dir | |||
from modelscope.utils.test_utils import test_level | |||
class SequenceClassificationTest(unittest.TestCase): | |||
@@ -43,6 +44,7 @@ class SequenceClassificationTest(unittest.TestCase): | |||
break | |||
print(r) | |||
@unittest.skipUnless(test_level() >= 2, 'skip test in current test level') | |||
def test_run(self): | |||
model_url = 'https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com' \ | |||
'/release/easynlp_modelzoo/alibaba-pai/bert-base-sst2.zip' | |||
@@ -67,6 +69,7 @@ class SequenceClassificationTest(unittest.TestCase): | |||
Tasks.text_classification, model=model, preprocessor=preprocessor) | |||
print(pipeline2('Hello world!')) | |||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level') | |||
def test_run_with_model_from_modelhub(self): | |||
model = Model.from_pretrained(self.model_id) | |||
preprocessor = SequenceClassificationPreprocessor( | |||
@@ -77,6 +80,7 @@ class SequenceClassificationTest(unittest.TestCase): | |||
preprocessor=preprocessor) | |||
self.predict(pipeline_ins) | |||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level') | |||
def test_run_with_model_name(self): | |||
text_classification = pipeline( | |||
task=Tasks.text_classification, model=self.model_id) | |||
@@ -85,6 +89,7 @@ class SequenceClassificationTest(unittest.TestCase): | |||
'glue', name='sst2', target='sentence', hub=Hubs.huggingface)) | |||
self.printDataset(result) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_default_model(self): | |||
text_classification = pipeline(task=Tasks.text_classification) | |||
result = text_classification( | |||
@@ -92,6 +97,7 @@ class SequenceClassificationTest(unittest.TestCase): | |||
'glue', name='sst2', target='sentence', hub=Hubs.huggingface)) | |||
self.printDataset(result) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_dataset(self): | |||
model = Model.from_pretrained(self.model_id) | |||
preprocessor = SequenceClassificationPreprocessor( | |||
@@ -8,6 +8,7 @@ from modelscope.models.nlp import PalmForTextGenerationModel | |||
from modelscope.pipelines import TextGenerationPipeline, pipeline | |||
from modelscope.preprocessors import TextGenerationPreprocessor | |||
from modelscope.utils.constant import Tasks | |||
from modelscope.utils.test_utils import test_level | |||
class TextGenerationTest(unittest.TestCase): | |||
@@ -15,7 +16,7 @@ class TextGenerationTest(unittest.TestCase): | |||
input1 = "今日天气类型='晴'&温度变化趋势='大幅上升'&最低气温='28℃'&最高气温='31℃'&体感='湿热'" | |||
input2 = "今日天气类型='多云'&体感='舒适'&最低气温='26℃'&最高气温='30℃'" | |||
@unittest.skip('skip temporarily to save test time') | |||
@unittest.skipUnless(test_level() >= 2, 'skip test in current test level') | |||
def test_run(self): | |||
cache_path = snapshot_download(self.model_id) | |||
preprocessor = TextGenerationPreprocessor( | |||
@@ -29,6 +30,7 @@ class TextGenerationTest(unittest.TestCase): | |||
print() | |||
print(f'input: {self.input2}\npipeline2: {pipeline2(self.input2)}') | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_model_from_modelhub(self): | |||
model = Model.from_pretrained(self.model_id) | |||
preprocessor = TextGenerationPreprocessor( | |||
@@ -37,11 +39,13 @@ class TextGenerationTest(unittest.TestCase): | |||
task=Tasks.text_generation, model=model, preprocessor=preprocessor) | |||
print(pipeline_ins(self.input1)) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_model_name(self): | |||
pipeline_ins = pipeline( | |||
task=Tasks.text_generation, model=self.model_id) | |||
print(pipeline_ins(self.input2)) | |||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level') | |||
def test_run_with_default_model(self): | |||
pipeline_ins = pipeline(task=Tasks.text_generation) | |||
print(pipeline_ins(self.input2)) | |||
@@ -7,6 +7,11 @@ import sys | |||
import unittest | |||
from fnmatch import fnmatch | |||
from modelscope.utils.logger import get_logger | |||
from modelscope.utils.test_utils import set_test_level, test_level | |||
logger = get_logger() | |||
def gather_test_cases(test_dir, pattern, list_tests): | |||
case_list = [] | |||
@@ -49,5 +54,9 @@ if __name__ == '__main__': | |||
'--pattern', default='test_*.py', help='test file pattern') | |||
parser.add_argument( | |||
'--test_dir', default='tests', help='directory to be tested') | |||
parser.add_argument( | |||
'--level', default=0, help='2 -- all, 1 -- p1, 0 -- p0') | |||
args = parser.parse_args() | |||
set_test_level(args.level) | |||
logger.info(f'TEST LEVEL: {test_level()}') | |||
main(args) |