提交 c3e05636 编写于 作者: W wusongqing

udpated docs

Signed-off-by: Nwusongqing <wusongqing@huawei.com>
上级 9191e3a2
# Test Framework Usage
## Overview
The delegator test framework provides a self-test framework (environment) for OpenHarmony applications. Using this framework, you can start an ability, schedule its lifecycle, listen for its state changes, run a shell command, and print the test result.
## Constraints
The APIs provided by the test framework can be used only in the test HAP. They take effect only after the test framework is started by running the **aa test** command or using the Integrated Development Environment (IDE).
## Starting the Test Framework
The test framework can be started by running the **aa test** command or using the IDE.
### Running aa test
You can run the **aa test** command to start the test framework. You can specify the **TestRunner** to be used and the package name or module name of the HAP where the **TestRunner** is located.
An example command in the FA model is as follows:
```javascript
aa test -p com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
```
An example command in the stage model is as follows:
```javascript
aa test -m com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
```
| Parameter | Mandatory| Description |
| --------------- | -------- | ------------------------------------------------------------ |
| -p | Yes | Package name of the HAP where the **TestRunner** is located. This parameter is used by the FA model. |
| -m | Yes | Module name of the HAP where the **TestRunner** is located. This parameter is used by the stage model. |
| -s unittest | Yes | Name of the **TestRunner** to be used. The TestRunner name must be the same as the file name. |
| -w | No | Timeout interval of a test case, in seconds. If this parameter is not specified, the test framework exits only after **finishTest** is invoked.|
| -s <key><value> | No | It can be any parameter in the key-value format. The entered parameters can be obtained in key-value mode through **AbilityDelegatorArgs.parameters**. For example, in **-s classname myTest**, **classname** is the key and **myTest** is the value.|
### Using the IDE
For details about how to start the IDE, see [IDE Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453#section1034420367508).
## Introduction to TestRunner
**TestRunner** is the entry class of the test framework test process. When the test process is started, the system calls related APIs in **TestRunner**. You need to inherit this class and override the **onPrepare** and **onRun** APIs. When creating an application template, the IDE initializes the default **TestRunner** and starts the default **TestAbility** in the **onRun** API. You can modify the test code of **TestAbility** or override **onPrepare** and **onRun** in **TestRunner** to implement your own test code. For details, see [TestRunner](../reference/apis/js-apis-testRunner.md).
## Introduction to AbilityMonitor
**AbilityMonitor** is provided by the test framework for binding to and listening for abilities. You can use **AbilityMonitor** to bind to an **Ability** instance and add **AbilityMonitor** to the listening list. After an ability is bound, the creation and lifecycle changes of the ability will trigger the related callback in **AbilityMonitor**. You can test and verify the ability in these callbacks. For details, see [AbilityMonitor](../reference/apis/js-apis-application-abilityMonitor.md).
**Example**
```javascript
import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
function onAbilityCreateCallback() {
console.info("onAbilityCreateCallback");
}
var monitor = {
abilityName: "abilityname",
onAbilityCreate: onAbilityCreateCallback
}
var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.addAbilityMonitor(monitor).then((void) => {
console.info("addAbilityMonitor promise");
});
```
## Introduction to AbilityDelegator
**AbilityDelegator** is a main function class of the test framework. It provides the functions of starting an ability, obtaining an **Ability** instance, scheduling the ability lifecycle, listening for the ability state, and printing test results.
**Modules to Import**
```javascript
import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
```
```javascript
var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
```
### Starting an Ability and Listening for the Ability State
Use **AbilityDelegator** and **AbilityMonitor** to start an ability, obtain an **Ability** instance, and listen for the ability state.
**Example**
```javascript
var abilityDelegator;
var ability;
var timeout = 100;
function onAbilityCreateCallback() {
console.info("onAbilityCreateCallback");
}
var monitor = {
abilityName: "abilityname",
onAbilityCreate: onAbilityCreateCallback
}
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.waitAbilityMonitor(monitor, timeout, (err, data) => {
ability = data;
console.info("waitAbilityMonitor callback");
});
var want = {
bundleName: "bundleName",
abilityName: "abilityName"
};
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.startAbility(want, (err, data) => {
console.info("startAbility callback");
});
```
### Scheduling the Ability Lifecycle
**AbilityDelegator** provides APIs to display and schedule the ability lifecycle and supports the foreground and background. It works with **AbilityMonitor** to listen for the ability lifecycle. For details, see [AbilityDelegator](../reference/apis/js-apis-application-abilityDelegator.md).
### Running a Shell Command
**AbilityDelegator** provides APIs to run shell commands. You can run a shell command in the test code. This feature takes effect only in the test environment.
**Example**
```javascript
var abilityDelegator;
var cmd = "cmd";
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.executeShellCommand(cmd, (err,data) => {
console.info("executeShellCommand callback");
});
```
......@@ -2,13 +2,13 @@
## Overview
### Concepts
The Page ability has the ArkUI and therefore provides the capability of interacting with users. When you create an ability in the integrated development environment (IDE), the IDE automatically creates template code. The capabilities related to the Page ability are exposed through the singleton **featureAbility**, and the lifecycle callbacks are exposed through the callback functions in **app.js/app.ets**.
The Page ability implements the ArkUI and therefore provides the capability of interacting with users. When you create an ability in the integrated development environment (IDE), the IDE automatically creates template code. The capabilities related to the Page ability are exposed through the singleton **featureAbility**, and the lifecycle callbacks are exposed through the callbacks in **app.js/app.ets**.
### Page Ability Lifecycle
The ability lifecycle is a general term for all states of an ability (either a Page or a Service ability), such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**.
**Ability Lifecycle**
The following figure shows the lifecycle state transition of the Page ability.
The ability lifecycle is a general term for all states of an ability, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**. The following figure shows the lifecycle state transition of the Page ability.
![PageAbility-Lifecycle](figures/page-ability-lifecycle.png)
......@@ -25,11 +25,11 @@ Description of ability lifecycle states:
- **BACKGROUND**: The ability returns to the background. After being re-activated, the ability enters the **ACTIVE** state. After being destroyed, the ability enters the **INITIAL** state.
**The following figure shows the lifecycle of the Page ability.**
**The following figure shows the relationship between lifecycle callbacks and lifecycle states of the Page ability.**
![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png)
You can override the lifecycle callback functions provided by the Page ability in **app.js/app.ets**.
You can override the lifecycle callbacks provided by the Page ability in the **app.js/app.ets** file. Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks.
## Development Guidelines
### Available APIs
......@@ -46,48 +46,48 @@ You can override the lifecycle callback functions provided by the Page ability i
### Starting a Local Page Ability
* Modules to Import
**Modules to Import**
```js
import featureAbility from '@ohos.ability.featureAbility'
```
import featureAbility from '@ohos.ability.featureAbility'
```
* Example
**Example**
```javascript
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
want:
{
action: "",
entities: [""],
type: "",
options: {
// Grant the permission to read the URI.
// Grant the permission to perform read operations on the URI.
authReadUriPermission: true,
// Grant the permission to write the URI.
// Grant the permission to perform write operations on the URI.
authWriteUriPermission: true,
// Forward the intent result to the origin ability.
// Support forwarding the intent result to the ability.
abilityForwardResult: true,
// Mark the ability start-up triggered by continuation.
// Enable abiligy continuation.
abilityContinuation: true,
// Specify that a component does not belong to ohos.
notOhosComponent: true,
// Specify whether an ability is started.
// Specify that an ability is started.
abilityFormEnabled: true,
// Grant the permission to persist the URI.
// Grant the permission for possible persisting on the URI.
authPersistableUriPermission: true,
// Grant the permission to persist the URI.
// Grant the permission for possible persisting on the prefix URI.
authPrefixUriPermission: true,
// Support distributed scheduling and start-up across multiple devices.
// Support distributed scheduling system startup on multiple devices.
abilitySliceMultiDevice: true,
// An ability using the Service template is started regardless of whether the
// host application has been started.
// A service ability is started regardless of whether the host application has been started.
startForegroundAbility: true,
// Install the specified ability if it is not installed.
installOnDemand: true,
// Return the result to the origin ability slice.
// Return the result to the ability slice.
abilitySliceForwardResult: true,
// Install the specified ability with the background mode if it is not installed.
// Install the specified ability with background mode if it is not installed.
installWithBackgroundMode: true
},
deviceId: "",
......@@ -95,14 +95,16 @@ featureAbility.startAbility({
abilityName: "com.example.startability.MainAbility",
uri: ""
},
},
);
},
);
```
You can also include **parameters** in the **want** parameter and set its value in the key-value format.
* Example
**Example**
```javascript
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
want:
{
bundleName: "com.example.startability",
......@@ -111,44 +113,111 @@ featureAbility.startAbility({
abilityName: "com.example.startability.MainAbility"
}
},
},
);
},
);
```
### Starting a Remote Page Ability
### Starting a Remote Page Ability (Applying only to System Applications)
>Note: The **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. Therefore, remote Page ability startup applies only to system applications.
* Modules to Import
**Modules to Import**
```
import featureAbility from '@ohos.ability.featureAbility'
import featureAbility from '@ohos.ability.featureAbility'
import deviceManager from '@ohos.distributedHardware.deviceManager';
```
* Example
**Example**
```ts
function onStartRemoteAbility() {
console.info('onStartRemoteAbility begin');
let params;
let wantValue = {
bundleName: 'ohos.samples.etsDemo',
abilityName: 'ohos.samples.etsDemo.RemoteAbility',
deviceId: getRemoteDeviceId(),
parameters: params
};
console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
featureAbility.startAbility({
want: wantValue
}).then((data) => {
console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
});
console.info('onStartRemoteAbility end');
}
```
```javascript
var promise = await featureAbility.startAbility({
want:
{
deviceId: this.deviceId,
bundleName: "com.example.test",
abilityName: "com.example.test.MainAbility",
},
}
);
Obtain **deviceId** from **DeviceManager**. The sample code is as follows:
```ts
import deviceManager from '@ohos.distributedHardware.deviceManager';
let dmClass;
function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) {
let list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
return;
}
console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId;
} else {
console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
}
}
```
In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows:
```ts
import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
import bundle from '@ohos.bundle';
async function RequestPermission() {
console.info('RequestPermission begin');
let array: Array<string> = ["ohos.permission.DISTRIBUTED_DATASYNC"];
let bundleFlag = 0;
let tokenID = undefined;
let userID = 100;
let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
tokenID = appInfo.accessTokenId;
let atManager = abilityAccessCtrl.createAtManager();
let requestPermissions: Array<string> = [];
for (let i = 0;i < array.length; i++) {
let result = await atManager.verifyAccessToken(tokenID, array[i]);
console.info("verifyAccessToken result:" + JSON.stringify(result));
if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
} else {
requestPermissions.push(array[i]);
}
}
console.info("requestPermissions:" + JSON.stringify(requestPermissions));
if (requestPermissions.length == 0 || requestPermissions == []) {
return;
}
let context = featureAbility.getContext();
context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
console.info("data:" + JSON.stringify(data));
console.info("data requestCode:" + data.requestCode);
console.info("data permissions:" + data.permissions);
console.info("data authResults:" + data.authResults);
});
console.info('RequestPermission end');
}
```
### Lifecycle APIs
**Table 2** Lifecycle callback functions
**Table 2** Lifecycle callbacks
| API | Description |
| ------------ | ------------------------------------------------------------ |
| onShow() | Invoked when the ability is switched from the background to the foreground. In this case, the ability is visible to users.|
| onHide() | Invoked when the ability is switched from the foreground to the background. In this case, the ability is invisible.|
| onDestroy() | Invoked when the ability is destroyed. In this callback, you can make preparations for app exit, such as recycling resources and clearing the cache.|
| onCreate() | Invoked when the ability is created for the first time. You can initialize the application in this callback.|
| onInactive() | Invoked when the ability loses focus. An ability loses focus before entering the background state.|
| onActive() | Invoked when the ability is switched to the foreground and gains focus. |
* Example
You need to override the lifecycle callback functions in **app.js/app.ets**. The IDE template generates **onCreate()** and **onDestroy()** by default. You need to override the other functions.
| onShow() | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.|
| onHide() | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible.|
| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for app exit, such as recycling resources and clearing the cache.|
| onCreate() | Called when the ability is created for the first time. You can initialize the application in this callback.|
| onInactive() | Called when the ability loses focus. An ability loses focus before entering the background state.|
| onActive() | Called when the ability is switched to the foreground and gains focus. |
**Example**
You need to override the lifecycle callbacks in **app.js/app.ets**. The IDE template generates **onCreate()** and **onDestroy()** by default. You need to override the other callbacks.
```javascript
export default {
onCreate() {
......@@ -174,6 +243,6 @@ export default {
### Development Example
The following sample is provided to help you better understand how to develop a Page ability:
- [DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS)
[DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS)
This sample describes how to start a local ability and remote ability.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册