## 多語言支持
編程語言在處理非拉丁字符時候有一個問題,帶重音符號的字符有多種編碼方式。比如,
字母`é`,有兩種編碼:一個單字符`é`(Unicode的`LATIN SMALL LETTER E WITH ACUTE`
(帶有尖標的小寫拉丁字母E))和字母`e`后跟上音標`?`的組合(`COMBINING ACUTE ACCENT`
(組合尖音標))。為了解決這個問題,就有了`normalization(標準化)`,一種讓["相同的字符串有一個唯一的二進制表示"](http://www.unicode.org/reports/tr15/)
的運算。
幸運的是,對ASCII文本(即不需要再被標準化的文本)進行標準化不會引起任何變化,且執行多次運算也不會有副作用。
因此,這個標準化函數在文本上調用不會有副作用的風險。
```javascript
// javascript
var unorm = require('unorm');
'some ASCII text' === unorm.nfd('some ASCII text');
unorm.nfd('Adéla?de Hervé') === unorm.nfd(unorm.nfd('Adéla?de Hervé'));
```
因此,當處理測試中的unicode文本時,你最好對預期的文本和從Appium接收到的文本都進行標準化。
進行標準化的方式有很多種,所以要確保對兩邊的字符串執行相同的運算!
```javascript
// javascript
var unorm = require('unorm');
driver
.elementByAccessibilityId('find')
.text()
.then(function (txt) {
unorm.nfd(txt).should.be(unorm.nfd("é ? ù ?"));
});
```
問題的端倪是對編碼后的unicode文本的斷言失敗但從報告上看,卻是相同的字符串:
```shell
AssertionError: expected 'Fran?ois Gérard' to deeply equal 'Fran?ois Gérard'
+ expected - actual
+"Fran?ois Gérard"
-"Fran?ois Gérard"
```
由于問題僅僅是編碼,輸出 _看起來_ 一樣。 標準化后,他們在程序里應該像看起來一樣是相等的。
### 查找器(Finders)
通過文本查找時也可能需要標準化。舉例來說,如果你在一個iOS應用里有一個名叫`Найти`的按鈕,
你需要在查找命令里標準化文本。
```javascript
// javascript
var unorm = require('unorm');
driver
.findElementByXPath(unorm.nfd("//UIAButton[@name='Найти']"))
.should.eventually.exist;
```
否則這個元素會找不到。
### 文本框(Text Fields)
默認情況下,iOS和Android的自動化工具都不支持通過鍵盤向可編輯的區域輸入non-ASCII字符。
#### iOS
Appium完全繞過鍵盤直接向iOS可編輯區域發送non-ASCII字符。雖然這樣在測試中允許了文本的輸入,但
必須記住的是任何通過鍵盤輸入觸發的業務邏輯都沒有被測試到。
如上所述,接收到的文本在被斷言前需要被標準化。
```javascript
// javascript
var unorm = require('unorm');
var testText = unorm.nfd("é ? ù ?");
driver
.elementsByClassName('UIATextField').at(1)
.sendKeys(testText)
.text()
.should.become(testText)
.nodeify(done);
```
#### Android
Android測試通過安裝和使用一個[特殊鍵盤](https://github.com/appium/io.appium.android.ime)
來允許Unicode輸入,它允許將文本像ASCII一樣在Appium和被測應用間傳遞。
為了使用這個功能,將`unicodeKeyboard` desired capability設置為`true`。如果鍵盤需要被還原成初始狀態,
將`resetKeyboard` desired capability也設置為`true`。不然設備上的Appium的Unicode鍵盤將會在測試完成后留用。
之后就可以通過使用`send_keys`向可編輯區域傳遞Unicode文本。
```javascript
// javascript
var desired = {
app: '/path/to/app',
deviceName: 'Android Emulator',
deviceVersion: '4.4',
platformName: 'Android',
unicodeKeyboard: true,
resetKeyboard: true
};
var testText = 'é ? ù ?';
driver
.elementByClassName('android.widget.EditText')
.sendKeys(testText)
.text()
.should.eventually.become(testText)
.nodeify(done);
```
本文由 [NativeZhang](https://github.com/NativeZhang) 翻譯,由 [lihuazhang](https://github.com/lihuazhang) 校驗。
- 關于TesterHome和MTSC
- 關于Appium
- 簡介
- Appium 客戶端
- 入門指南
- 已支持的平臺
- API 文檔
- Appium驅動
- XCUITest (iOS)
- XCUITest Real Devices (iOS)
- UIAutomation (iOS)
- UIAutomation Safari Launcher (iOS)
- UIAutomator (Android)
- UIAutomator2 (Android)
- Espresso (Android)
- Windows
- Mac
- Appium命令
- Status
- Execute Mobile Command
- Session
- Create
- End
- Get Session Capabilities
- Go Back
- Screenshot
- Source
- Timeouts
- Timeouts
- Implicit Wait
- Async Script
- Orientation
- Get Orientation
- Set Orientation
- Geolocation
- Get Geolocation
- Set Geolocation
- Logs
- Get Log Types
- Get Logs
- Events
- Log event
- Get events
- Settings
- Update Settings
- Get Device Settings
- Settings
- Update Settings
- Get Device Settings
- Execute Driver Script
- Device
- Activity
- Start Activity
- Current Activity
- Current Package
- App
- Install App
- Is App Installed
- Launch App
- Background App
- Close App
- Reset App
- Remove App
- Activate App
- Terminate App
- Get App State
- Get App Strings
- End Test Coverage
- Clipboard
- Get Clipboard
- Set Clipboard
- Emulator
- Power AC
- Power Capacity
- Files
- Push File
- Pull File
- Pull Folder
- Interactions
- Shake
- Lock
- Unlock
- Is Locked
- Rotate
- Keys
- Press keycode
- Long press keycode
- Hide Keyboard
- Is Keyboard Shown
- Network
- Toggle Airplane Mode
- Toggle Data
- Toggle WiFi
- Toggle Location Services
- Send SMS
- GSM Call
- GSM Signal
- GSM Voice
- Network Speed
- Performance Data
- Get Performance Data
- Performance Data Types
- Screen Recording
- Start Screen Recording
- Stop Screen Recording
- Simulator
- Perform Touch ID
- Toggle Touch ID Enrollment
- System
- Open Notifications
- System Bars
- System Time
- Display density
- Authentication
- Finger Print
- Element
- Find Element
- Find Elements
- Actions
- Click
- Send Keys
- Clear
- Attributes
- Text
- Name
- Attribute
- Selected
- Enabled
- Displayed
- Location
- Size
- Rect
- CSS Property
- Location in View
- Other
- Submit
- Active Element
- Equals Element
- Context
- Get Context
- Get All Contexts
- Set Context
- Interactions
- Mouse
- Move To
- Click
- Double Click
- Button Down
- Button Up
- Touch
- Single Tap
- Double Tap
- Move
- Touch Down
- Touch Up
- Long Press
- Scroll
- Flick
- Multi Touch Perform
- Touch Perform
- W3C Actions
- Web
- Window
- Set Window
- Close Window
- Get Handle
- Get Handles
- Get Title
- Get Window Size
- Set Window Size
- Get Window Position
- Set Window Position
- Maximize Window
- Navigation
- Go to URL
- Get URL
- Back
- Forward
- Refresh
- Storage
- Get All Cookies
- Set Cookie
- Delete Cookie
- Delete All Cookies
- Frame
- Switch to Frame
- Switch to Parent Frame
- Execute Async
- Execute
- 編寫 & 運行Appium腳本
- Running Tests
- Desired Capabilities
- The --default-capabilities flag
- Finding Elements
- Touch Actions
- CLI Arguments
- Server Security
- Web/Web Views
- Mobile Web Testing
- Automating Hybrid Apps
- Using ios-webkit-debug-proxy
- Using Chromedriver
- Image Comparison
- iOS
- Low-Level Insights on iOS Input Events
- XCUITest Mobile Gestures
- XCUITest Mobile App Management
- iOS Pasteboard Guide
- iOS Predicate Guide
- iOS Touch ID Guide
- iOS Install Certificate
- tvOS support
- Pushing/Pulling files
- Audio Capture
- Android
- Low-Level Insights on Android Input Events
- UiSelector Guide
- Espresso Datamatcher Guide
- Android Code Coverage Guide
- Activities Startup Troubleshooting Guide
- How To Execute Shell Commands On The Remote Device
- Android Device Screen Streaming
- How To Emulate IME Actions Generation
- How To Test Android App Bundle
- Other
- Reset Strategies
- Network Connection Guide
- Using Unicode with Appium
- Troubleshooting
- Tutorial
- Swipe Tutorial
- Screen
- Element
- Partial screen
- Simple
- Multiple scroll views
- Add scroll layout
- Tricks and Tips
- Screen
- Element
- Element search
- Fast
- Slow
- Guide
- 進階概念
- 定位圖像中的元素
- 使用定位元素的插件
- 遷移到 XCUITest
- 在 Appium 中使用 Selenium Grid
- Appium Logs Filtering
- 跨域 iframes
- 使用自定義 WDA 服務器
- 使用不同版本的 Xcode 運行
- The Event Timings API
- 并行測試的設置
- The Settings API
- Memory Collection
- 向Appium項目做貢獻
- 從源代碼運行 Appium
- 開發者概述
- 標準開發命令
- Appium 風格指南
- 如何編寫文檔
- Appium 包結構
- 鳴謝