mirror of
https://gitee.com/openharmony/testfwk_developer_test
synced 2024-11-26 17:20:48 +00:00
add js test framework
Signed-off-by: renxiang <renxiang11@huawei.com>
This commit is contained in:
parent
fd450883b6
commit
15f37661bc
27
examples/app_info/BUILD.gn
Normal file
27
examples/app_info/BUILD.gn
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
###############################################################################
|
||||
config("app_info_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
ohos_shared_library("app_info") {
|
||||
sources = []
|
||||
public_configs = [ ":app_info_config" ]
|
||||
subsystem_name = "subsystem_examples"
|
||||
}
|
||||
###############################################################################
|
23
examples/app_info/test/BUILD.gn
Normal file
23
examples/app_info/test/BUILD.gn
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/test.gni")
|
||||
|
||||
#################################group#########################################
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = []
|
||||
|
||||
deps += [ "unittest/common/get_app_info:unittest" ]
|
||||
}
|
||||
###############################################################################
|
28
examples/app_info/test/unittest/common/get_app_info/BUILD.gn
Normal file
28
examples/app_info/test/unittest/common/get_app_info/BUILD.gn
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/test.gni")
|
||||
|
||||
module_output_path = "subsystem_examples/app_info"
|
||||
|
||||
ohos_js_unittest("GetAppInfoJsTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
hap_profile = "./config.json"
|
||||
certificate_profile = "//test/developertest/signature/openharmony_sx.p7b"
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [ ":GetAppInfoJsTest" ]
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import app from '@system.app'
|
||||
|
||||
import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index'
|
||||
|
||||
describe("AppInfoTest", function () {
|
||||
beforeAll(function() {
|
||||
/*
|
||||
* @tc.setup: setup invoked before all testcases
|
||||
*/
|
||||
console.info('beforeAll caled')
|
||||
})
|
||||
|
||||
afterAll(function() {
|
||||
/*
|
||||
* @tc.teardown: teardown invoked after all testcases
|
||||
*/
|
||||
console.info('afterAll caled')
|
||||
})
|
||||
|
||||
beforeEach(function() {
|
||||
/*
|
||||
* @tc.setup: setup invoked before each testcases
|
||||
*/
|
||||
console.info('beforeEach caled')
|
||||
})
|
||||
|
||||
afterEach(function() {
|
||||
/*
|
||||
* @tc.teardown: teardown invoked after each testcases
|
||||
*/
|
||||
console.info('afterEach caled')
|
||||
})
|
||||
|
||||
/*
|
||||
* @tc.name:appInfoTest001
|
||||
* @tc.desc:verify app info is not null
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: Issue Number
|
||||
*/
|
||||
it("appInfoTest001", 0, function () {
|
||||
var info = app.getInfo()
|
||||
expect(info != null).assertEqual(true)
|
||||
})
|
||||
|
||||
/*
|
||||
* @tc.name:appInfoTest002
|
||||
* @tc.desc:verify app info name and code
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: Issue Number
|
||||
*/
|
||||
it("appInfoTest002", 0, function () {
|
||||
var info = app.getInfo()
|
||||
expect(info.versionName).assertEqual('')
|
||||
expect(info.versionCode).assertEqual('0')
|
||||
})
|
||||
|
||||
})
|
@ -0,0 +1,59 @@
|
||||
{
|
||||
"app": {
|
||||
"bundleName": "com.example.myapplication",
|
||||
"vendor": "example",
|
||||
"version": {
|
||||
"code": 1,
|
||||
"name": "1.0"
|
||||
},
|
||||
"apiVersion": {
|
||||
"compatible": 4,
|
||||
"target": 5
|
||||
}
|
||||
},
|
||||
"deviceConfig": {},
|
||||
"module": {
|
||||
"package": "com.example.myapplication",
|
||||
"name": ".MyApplication",
|
||||
"deviceType": [
|
||||
"phone"
|
||||
],
|
||||
"distro": {
|
||||
"deliveryWithInstall": true,
|
||||
"moduleName": "entry",
|
||||
"moduleType": "entry"
|
||||
},
|
||||
"abilities": [
|
||||
{
|
||||
"skills": [
|
||||
{
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
],
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "com.example.myapplication.MainAbility",
|
||||
"icon": "$media:icon",
|
||||
"description": "$string:mainability_description",
|
||||
"label": "MyApplication",
|
||||
"type": "page",
|
||||
"launchType": "standard"
|
||||
}
|
||||
],
|
||||
"js": [
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"name": "default",
|
||||
"window": {
|
||||
"designWidth": 720,
|
||||
"autoDesignWidth": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -3,11 +3,13 @@
|
||||
"parts": {
|
||||
"subsystem_examples": {
|
||||
"module_list": [
|
||||
"//test/developertest/examples/app_info:app_info",
|
||||
"//test/developertest/examples/detector:detector",
|
||||
"//test/developertest/examples/calculator:calculator",
|
||||
"//test/developertest/examples/calculator:calculator_static"
|
||||
],
|
||||
"test_list": [
|
||||
"//test/developertest/examples/app_info/test:unittest",
|
||||
"//test/developertest/examples/calculator/test:unittest",
|
||||
"//test/developertest/examples/calculator/test:fuzztest",
|
||||
"//test/developertest/examples/detector/test:unittest",
|
||||
|
24
libs/js_template/src/main/js/default/app.js
Normal file
24
libs/js_template/src/main/js/default/app.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import device from '@system.device';
|
||||
|
||||
export default {
|
||||
onCreate() {
|
||||
console.info('AceApplication onCreate');
|
||||
},
|
||||
onDestroy() {
|
||||
console.info('AceApplication onDestroy');
|
||||
}
|
||||
};
|
6
libs/js_template/src/main/js/default/i18n/en-US.json
Normal file
6
libs/js_template/src/main/js/default/i18n/en-US.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"strings": {
|
||||
"hello": "TargetName",
|
||||
"world": ""
|
||||
}
|
||||
}
|
38
libs/js_template/src/main/js/default/pages/index/index.css
Normal file
38
libs/js_template/src/main/js/default/pages/index/index.css
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 60px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
margin: 10px;
|
||||
}
|
||||
.btn {
|
||||
width: 50%;
|
||||
height: 100px;
|
||||
font-size: 40px;
|
||||
}
|
21
libs/js_template/src/main/js/default/pages/index/index.hml
Normal file
21
libs/js_template/src/main/js/default/pages/index/index.hml
Normal file
@ -0,0 +1,21 @@
|
||||
<!--
|
||||
Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<div class="container" onswipe="touchMove">
|
||||
<text class="title">
|
||||
{{ $t('strings.hello') }} {{title}}
|
||||
</text>
|
||||
<input class="btn" type="button" value="{{ $t('strings.next') }}" onclick="onclick"></input>
|
||||
</div>
|
45
libs/js_template/src/main/js/default/pages/index/index.js
Normal file
45
libs/js_template/src/main/js/default/pages/index/index.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import app from '@system.app'
|
||||
|
||||
import {Core, ExpectExtend} from 'deccjsunit/index'
|
||||
|
||||
export default {
|
||||
data: {
|
||||
title: ""
|
||||
},
|
||||
onInit() {
|
||||
this.title = this.$t('strings.world');
|
||||
},
|
||||
onShow() {
|
||||
console.info('onShow finish')
|
||||
const core = Core.getInstance()
|
||||
const expectExtend = new ExpectExtend({
|
||||
'id': 'extend'
|
||||
})
|
||||
|
||||
core.addService('expect', expectExtend)
|
||||
core.init()
|
||||
|
||||
const configService = core.getDefaultService('config')
|
||||
configService.setConfig(this)
|
||||
|
||||
require('../../test/List.test')
|
||||
core.execute()
|
||||
},
|
||||
onReady() {
|
||||
},
|
||||
}
|
14
libs/js_template/src/main/js/default/test/List.test.js
Normal file
14
libs/js_template/src/main/js/default/test/List.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
12
libs/js_template/src/main/resources/base/element/string.json
Normal file
12
libs/js_template/src/main/resources/base/element/string.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "JsTestApp"
|
||||
},
|
||||
{
|
||||
"name": "mainability_description",
|
||||
"value": "hap sample empty page"
|
||||
}
|
||||
]
|
||||
}
|
BIN
libs/js_template/src/main/resources/base/media/icon.png
Normal file
BIN
libs/js_template/src/main/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
signature/openharmony_sx.p7b
Normal file
BIN
signature/openharmony_sx.p7b
Normal file
Binary file not shown.
@ -21,6 +21,7 @@ from xdevice import platform_logger
|
||||
from core.utils import scan_support_product
|
||||
from core.config.config_manager import UserConfigManager
|
||||
from core.build.select_targets import SelectTargets
|
||||
from core.build.pretreat_targets import PretreatTargets
|
||||
from core.build.build_testcases import BuildTestcases
|
||||
from core.command.gen import Gen
|
||||
|
||||
@ -95,6 +96,9 @@ class BuildManager(object):
|
||||
LOG.warning("No build target found.")
|
||||
return False
|
||||
|
||||
pretreat = PretreatTargets(target_list)
|
||||
pretreat.pretreat_targets_from_list()
|
||||
|
||||
build_cfg_filepath = os.path.join(project_root_path,
|
||||
"test",
|
||||
"developertest",
|
||||
@ -111,6 +115,7 @@ class BuildManager(object):
|
||||
para.productform,
|
||||
"make_temp_test")
|
||||
self._make_gn_file(build_cfg_filepath, [])
|
||||
pretreat.disassemble_targets_from_list()
|
||||
|
||||
return build_result
|
||||
|
||||
|
149
src/core/build/pretreat_targets.py
Normal file
149
src/core/build/pretreat_targets.py
Normal file
@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
|
||||
from core.constants import JsTestConst
|
||||
from xdevice import platform_logger
|
||||
|
||||
LOG = platform_logger("PretreatTargets")
|
||||
|
||||
|
||||
##############################################################################
|
||||
##############################################################################
|
||||
|
||||
class PretreatTargets(object):
|
||||
def __init__(self, target_list):
|
||||
self.path_list = []
|
||||
self.name_list = []
|
||||
self.target_list = target_list
|
||||
|
||||
def pretreat_targets_from_list(self):
|
||||
path_list, name_list = self._parse_target_info()
|
||||
self._pretreat_by_target_name(path_list, name_list)
|
||||
|
||||
def disassemble_targets_from_list(self):
|
||||
self._disassemble_by_target_name(self.path_list, self.name_list)
|
||||
|
||||
def _parse_target_info(self):
|
||||
path_list = []
|
||||
name_list = []
|
||||
|
||||
for line in self.target_list:
|
||||
path = line.split(':')[0][2:]
|
||||
name = line.split(':')[1].split('(')[0]
|
||||
path_list.append(path)
|
||||
name_list.append(name)
|
||||
|
||||
return path_list, name_list
|
||||
|
||||
def _pretreat_by_target_name(self, path_list, name_list):
|
||||
for name, path in zip(name_list, path_list):
|
||||
if name.endswith("JsTest"):
|
||||
if self._pretreat_js_target(path, name):
|
||||
self.path_list.append(path)
|
||||
self.name_list.append(name)
|
||||
LOG.info("js test %s pretreat success" % name)
|
||||
|
||||
def _pretreat_js_target(self, path, name):
|
||||
template_path = os.path.join(sys.framework_root_dir, "libs",
|
||||
"js_template", "src")
|
||||
target_path = os.path.join(sys.source_code_root_path, path)
|
||||
config_path = os.path.join(target_path, "config.json")
|
||||
gn_path = os.path.join(target_path, "BUILD.gn")
|
||||
gn_bak_path = os.path.join(target_path, "BuildBak")
|
||||
test_path = os.path.join(target_path, "src", "main", "js",
|
||||
"default", "test")
|
||||
if not os.path.exists(config_path):
|
||||
LOG.error("js test needs config.json file")
|
||||
return False
|
||||
if not os.path.exists(gn_path):
|
||||
LOG.error("js test needs BUILD.gn file")
|
||||
return False
|
||||
LOG.info("target_path: %s" % target_path)
|
||||
|
||||
#modify BUILD.gn file to compile hap
|
||||
output_path = self._parse_output_path_in_gn(gn_path)
|
||||
if output_path == "":
|
||||
LOG.error(" BUILD.gn needs 'module_output_path'")
|
||||
return
|
||||
os.rename(gn_path, gn_bak_path)
|
||||
template_args = {'output_path': output_path, 'suite_name': name}
|
||||
with open(gn_path, 'w') as filehandle:
|
||||
filehandle.write(JsTestConst.BUILD_GN_FILE_TEMPLATE %
|
||||
template_args)
|
||||
|
||||
#copy js hap template to target path
|
||||
shutil.copytree(template_path, os.path.join(target_path, "src"))
|
||||
shutil.copy(config_path, os.path.join(target_path, "src", "main"))
|
||||
file_name = os.listdir(target_path)
|
||||
for file in file_name:
|
||||
if file.endswith(".js"):
|
||||
LOG.info("file: %s" % file)
|
||||
shutil.copy(os.path.join(target_path, file), test_path)
|
||||
with open(os.path.join(test_path, "List.test.js"), 'a') \
|
||||
as list_data:
|
||||
list_data.write("require('./%s')" % file)
|
||||
|
||||
#modify i18n json file
|
||||
i18n_path = os.path.join(target_path, "src", "main", "js",
|
||||
"default", "i18n", "en-US.json")
|
||||
json_data = ""
|
||||
with open(i18n_path, 'r') as i18n_file:
|
||||
lines = i18n_file.readlines()
|
||||
for line in lines:
|
||||
if "TargetName" in line:
|
||||
line = line.replace("TargetName", name)
|
||||
json_data += line
|
||||
with open(i18n_path, 'w') as i18n_file:
|
||||
i18n_file.write(json_data)
|
||||
return True
|
||||
|
||||
def _parse_output_path_in_gn(self, gn_path):
|
||||
output_path = ""
|
||||
with open(gn_path, 'r') as gn_file:
|
||||
for line in gn_file.readlines():
|
||||
if line.startswith("module_output_path"):
|
||||
output_path = line.split()[2].strip('"')
|
||||
break
|
||||
return output_path
|
||||
|
||||
def _disassemble_by_target_name(self, path_list, name_list):
|
||||
for name, path in zip(name_list, path_list):
|
||||
LOG.info("name: %s path: %s" % (name, path))
|
||||
if name.endswith("JsTest"):
|
||||
self._disassemble_js_target(path, name)
|
||||
LOG.info("js test %s disassemble success" % name)
|
||||
|
||||
def _disassemble_js_target(self, path, name):
|
||||
target_path = os.path.join(sys.source_code_root_path, path)
|
||||
src_path = os.path.join(target_path, "src")
|
||||
gn_path = os.path.join(target_path, "BUILD.gn")
|
||||
gn_bak_path = os.path.join(target_path, "BuildBak")
|
||||
|
||||
if os.path.exists(src_path):
|
||||
shutil.rmtree(src_path)
|
||||
if os.path.exists(gn_path) and os.path.exists(gn_bak_path):
|
||||
os.remove(gn_path)
|
||||
os.rename(gn_bak_path, gn_path)
|
||||
|
||||
##############################################################################
|
||||
##############################################################################
|
@ -75,3 +75,51 @@ class ConfigFileConst(object):
|
||||
def user_config_file(self):
|
||||
return ConfigFileConst.USERCONFIG_FILEPATH
|
||||
|
||||
|
||||
class JsTestConst(object):
|
||||
BUILD_GN_FILE_TEMPLATE = """\
|
||||
# Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/test.gni")
|
||||
|
||||
module_output_path = "%(output_path)s"
|
||||
|
||||
ohos_js_unittest("%(suite_name)s") {
|
||||
module_out_path = module_output_path
|
||||
hap_profile = "./src/main/config.json"
|
||||
deps = [
|
||||
":%(suite_name)s_js_assets",
|
||||
":%(suite_name)s_resources",
|
||||
]
|
||||
|
||||
certificate_profile = "//test/developertest/signature/openharmony_sx.p7b"
|
||||
hap_name = "%(suite_name)s"
|
||||
}
|
||||
ohos_js_assets("%(suite_name)s_js_assets") {
|
||||
source_dir = "./src/main/js/default"
|
||||
}
|
||||
ohos_resources("%(suite_name)s_resources") {
|
||||
sources = [ "./src/main/resources" ]
|
||||
hap_profile = "./src/main/config.json"
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [ ":%(suite_name)s" ]
|
||||
}
|
||||
"""
|
||||
|
||||
@property
|
||||
def build_gn_template(self):
|
||||
return JsTestConst.BUILD_GN_FILE_TEMPLATE
|
||||
|
@ -16,20 +16,26 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import time
|
||||
import platform
|
||||
import zipfile
|
||||
from dataclasses import dataclass
|
||||
|
||||
from xdevice import DeviceTestType
|
||||
from xdevice import DeviceLabelType
|
||||
from xdevice import ExecuteTerminate
|
||||
from xdevice import DeviceError
|
||||
from xdevice import ShellHandler
|
||||
|
||||
from xdevice import IDriver
|
||||
from xdevice import platform_logger
|
||||
from xdevice import Plugin
|
||||
from xdevice import get_plugin
|
||||
from xdevice_extension._core.constants import CommonParserType
|
||||
from core.utils import get_decode
|
||||
from core.utils import get_fuzzer_path
|
||||
from core.config.resource_manager import ResourceManager
|
||||
@ -38,6 +44,7 @@ from core.config.config_manager import FuzzerConfigManager
|
||||
|
||||
__all__ = [
|
||||
"CppTestDriver",
|
||||
"JSUnitTestDriver",
|
||||
"disable_keyguard",
|
||||
"GTestConst"]
|
||||
|
||||
@ -564,3 +571,239 @@ class CppTestDriver(IDriver):
|
||||
|
||||
##############################################################################
|
||||
##############################################################################
|
||||
|
||||
@Plugin(type=Plugin.DRIVER, id=DeviceTestType.jsunit_test)
|
||||
class JSUnitTestDriver(IDriver):
|
||||
"""
|
||||
JSUnitTestDriver is a Test that runs a native test package on given device.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.config = None
|
||||
self.result = ""
|
||||
self.start_time = None
|
||||
self.ability_name = ""
|
||||
self.package_name = ""
|
||||
|
||||
def __check_environment__(self, device_options):
|
||||
pass
|
||||
|
||||
def __check_config__(self, config):
|
||||
pass
|
||||
|
||||
def __result__(self):
|
||||
return self.result if os.path.exists(self.result) else ""
|
||||
|
||||
def __execute__(self, request):
|
||||
try:
|
||||
LOG.info("developertest driver")
|
||||
self.result = os.path.join(request.config.report_path,
|
||||
"result",
|
||||
'.'.join((request.get_module_name(),
|
||||
"xml")))
|
||||
self.config = request.config
|
||||
self.config.target_test_path = DEFAULT_TEST_PATH
|
||||
self.config.device = request.config.environment.devices[0]
|
||||
|
||||
suite_file = request.root.source.source_file
|
||||
if not suite_file:
|
||||
LOG.error("test source '%s' not exists" %
|
||||
request.root.source.source_string)
|
||||
return
|
||||
|
||||
if not self.config.device:
|
||||
result = ResultManager(suite_file, self.config)
|
||||
result.set_is_coverage(False)
|
||||
result.make_empty_result_file(
|
||||
"No test device is found")
|
||||
return
|
||||
|
||||
package_name, ability_name = self._get_package_and_ability_name(
|
||||
suite_file)
|
||||
self.package_name = package_name
|
||||
self.ability_name = ability_name
|
||||
self.config.test_hap_out_path = \
|
||||
"/data/data/%s/files/" % self.package_name
|
||||
|
||||
self._init_jsunit_test()
|
||||
self._run_jsunit(suite_file)
|
||||
self.generate_console_output(request)
|
||||
|
||||
finally:
|
||||
self.config.device.stop_catch_device_log()
|
||||
|
||||
def _init_jsunit_test(self):
|
||||
self.config.device.hdc_command("target mount")
|
||||
self.config.device.execute_shell_command(
|
||||
"rm -rf %s" % self.config.target_test_path)
|
||||
self.config.device.execute_shell_command(
|
||||
"mkdir -p %s" % self.config.target_test_path)
|
||||
self.config.device.execute_shell_command(
|
||||
"mount -o rw,remount,rw /%s" % "system")
|
||||
self.config.device.hdc_command("shell hilog -r")
|
||||
|
||||
|
||||
def _run_jsunit(self, suite_file):
|
||||
filename = os.path.basename(suite_file)
|
||||
|
||||
resource_manager = ResourceManager()
|
||||
resource_data_dic, resource_dir = \
|
||||
resource_manager.get_resource_data_dic(suite_file)
|
||||
resource_manager.process_preparer_data(resource_data_dic, resource_dir,
|
||||
self.config.device)
|
||||
|
||||
main_result = self._install_hap(suite_file)
|
||||
result = ResultManager(suite_file, self.config)
|
||||
|
||||
if main_result:
|
||||
self._execute_hapfile_jsunittest()
|
||||
self._uninstall_hap(self.package_name)
|
||||
else:
|
||||
self.result = result.get_test_results("Error: install hap failed")
|
||||
LOG.error("Error: install hap failed")
|
||||
|
||||
resource_manager.process_cleaner_data(resource_data_dic, resource_dir,
|
||||
self.config.device)
|
||||
|
||||
def generate_console_output(self, request):
|
||||
report_name = request.get_module_name()
|
||||
parsers = get_plugin(
|
||||
Plugin.PARSER, CommonParserType.jsunit)
|
||||
if parsers:
|
||||
parsers = parsers[:1]
|
||||
for listener in request.listeners:
|
||||
listener.device_sn = self.config.device.device_sn
|
||||
parser_instances = []
|
||||
|
||||
for parser in parsers:
|
||||
parser_instance = parser.__class__()
|
||||
parser_instance.suites_name = "{}_suites".format(report_name)
|
||||
parser_instance.suites_name = request.listeners
|
||||
parser_instance.listeners = request.listeners
|
||||
parser_instances.append(parser_instance)
|
||||
handler = ShellHandler(parser_instances)
|
||||
|
||||
from xdevice_extension._core import utils
|
||||
command = "hdc_std -t %s shell hilog -x " % self.config.device. \
|
||||
device_sn
|
||||
|
||||
output = utils.start_standing_subprocess(command, return_result=True)
|
||||
LOG.debug("start to parsing hilog")
|
||||
handler.__read__(output)
|
||||
handler.__done__()
|
||||
|
||||
|
||||
def _execute_hapfile_jsunittest(self):
|
||||
_unlock_screen(self.config.device)
|
||||
_unlock_device(self.config.device)
|
||||
|
||||
try:
|
||||
return_message = self.start_hap_activity()
|
||||
except (ExecuteTerminate, DeviceError) as exception:
|
||||
return_message = str(exception.args)
|
||||
|
||||
_lock_screen(self.config.device)
|
||||
return return_message
|
||||
|
||||
def _install_hap(self, suite_file):
|
||||
message = self.config.device.hdc_command("install %s" % suite_file)
|
||||
message = str(message).rstrip()
|
||||
if message == "" or "success" in message:
|
||||
return_code = True
|
||||
if message != "":
|
||||
LOG.info(message)
|
||||
else:
|
||||
return_code = False
|
||||
if message != "":
|
||||
LOG.warning(message)
|
||||
|
||||
_sleep_according_to_result(return_code)
|
||||
return return_code
|
||||
|
||||
def start_hap_activity(self):
|
||||
try:
|
||||
command = "aa start -d 123 -a %s.MainAbility -b %s" \
|
||||
% (self.package_name, self.package_name)
|
||||
self.start_time = time.time()
|
||||
result_value = self.config.device.execute_shell_command(
|
||||
command, timeout=TIME_OUT)
|
||||
LOG.info("result_value [[[[[%s]]]]]" % result_value)
|
||||
|
||||
if "success" in str(result_value).lower():
|
||||
LOG.info("execute %s's testcase success. result value=%s"
|
||||
% (self.package_name, result_value))
|
||||
time.sleep(60)
|
||||
else:
|
||||
LOG.info("execute %s's testcase failed. result value=%s"
|
||||
% (self.package_name, result_value))
|
||||
|
||||
_sleep_according_to_result(result_value)
|
||||
return_message = result_value
|
||||
except (ExecuteTerminate, DeviceError) as exception:
|
||||
return_message = exception.args
|
||||
|
||||
return return_message
|
||||
|
||||
def _uninstall_hap(self, package_name):
|
||||
return_message = self.config.device.execute_shell_command(
|
||||
"bm uninstall -n %s" % package_name)
|
||||
_sleep_according_to_result(return_message)
|
||||
return return_message
|
||||
|
||||
@staticmethod
|
||||
def _get_package_and_ability_name(hap_filepath):
|
||||
package_name = ""
|
||||
ability_name = ""
|
||||
|
||||
if os.path.exists(hap_filepath):
|
||||
filename = os.path.basename(hap_filepath)
|
||||
|
||||
#unzip the hap file
|
||||
hap_bak_path = os.path.abspath(os.path.join(
|
||||
os.path.dirname(hap_filepath),
|
||||
"%s.bak" % filename))
|
||||
zf_desc = zipfile.ZipFile(hap_filepath)
|
||||
try:
|
||||
zf_desc.extractall(path=hap_bak_path)
|
||||
except RuntimeError as error:
|
||||
print(error)
|
||||
zf_desc.close()
|
||||
|
||||
#verify config.json file
|
||||
app_profile_path = os.path.join(hap_bak_path, "config.json")
|
||||
if not os.path.exists(app_profile_path):
|
||||
print("file %s not exist" % app_profile_path)
|
||||
return package_name, ability_name
|
||||
|
||||
if os.path.isdir(app_profile_path):
|
||||
print("%s is a folder, and not a file" % app_profile_path)
|
||||
return package_name, ability_name
|
||||
|
||||
#get package_name and ability_name value
|
||||
load_dict = {}
|
||||
with open(app_profile_path, 'r') as load_f:
|
||||
load_dict = json.load(load_f)
|
||||
profile_list = load_dict.values()
|
||||
for profile in profile_list:
|
||||
package_name = profile.get("package")
|
||||
if not package_name:
|
||||
continue
|
||||
|
||||
abilities = profile.get("abilities")
|
||||
for abilitie in abilities:
|
||||
abilities_name = abilitie.get("name")
|
||||
if abilities_name.startswith("."):
|
||||
ability_name = package_name + abilities_name[
|
||||
abilities_name.find("."):]
|
||||
else:
|
||||
ability_name = abilities_name
|
||||
break
|
||||
break
|
||||
|
||||
#delete hap_bak_path
|
||||
if os.path.exists(hap_bak_path):
|
||||
shutil.rmtree(hap_bak_path)
|
||||
else:
|
||||
print("file %s not exist" % hap_filepath)
|
||||
|
||||
return package_name, ability_name
|
||||
|
@ -30,6 +30,7 @@ TESTFILE_TYPE_DATA_DIC = {
|
||||
"PYT": [],
|
||||
"CXX": [],
|
||||
"BIN": [],
|
||||
"JST": [],
|
||||
}
|
||||
FILTER_SUFFIX_NAME_LIST = [".TOC", ".info", ".pyc"]
|
||||
|
||||
@ -109,7 +110,7 @@ class TestCaseManager(object):
|
||||
if suffix_name == ".dex":
|
||||
suite_file_dictionary["DEX"].append(suite_file)
|
||||
elif suffix_name == ".hap":
|
||||
suite_file_dictionary["HAP"].append(suite_file)
|
||||
suite_file_dictionary["JST"].append(suite_file)
|
||||
elif suffix_name == ".py":
|
||||
if not self.check_python_test_file(suite_file):
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user