簡體   English   中英

發出同步 HTTP GET 請求或調用 JavaScript 中的 shell 腳本來自 Z1BZCBD1UID3E91

[英]Issuing a synchronous HTTP GET request or invoking shell script in JavaScript from iOS UIAutomation

我正在嘗試使用 Apple 的 UIAutomation 為具有服務器端組件的 iOS 應用程序編寫單元測試。 為了在各種狀態下設置測試服務器(以及模擬兩個客戶端通過我的服務器進行通信),我想在我的基於 javascript 的測試中發出 HTTP 獲取請求。

Can anyone provide an example of how to either issue HTTP GET requests directly from within UIAutomation javascript tests, or how to invoke a shell script from within my UIAutomation javascript tests?

FWIW,UIAutomation 運行時中缺少所有瀏覽器可用的大多數核心對象。 嘗試使用 XMLHTTPRequest 例如,您將收到一個異常報告,它無法找到該變量。

謝謝!

伙計們,

我可以通過向 iOS 客戶端發送 HTTP 請求來處理並在 UIAlertView 中返回結果來解決此問題。 請注意,所有 iOS 代碼修改都包含在 #if DEBUG 條件編譯指令中。

首先,將您的客戶端設置為在設備抖動時發送通知。 閱讀這篇文章了解更多信息

接下來,在您的 iOS 主應用程序委托中添加以下代碼:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(deviceShakenShowDebug:)
                                             name:@"DeviceShaken" 
                                           object:nil];

然后添加一個看起來像這樣的方法:

- (void) deviceShakenShowDebug:(id)sender
{
    if (!self.textFieldEnterDebugArgs)
    {
        self.textFieldEnterDebugArgs = [[[UITextField alloc] initWithFrame:CGRectMake(0, 0, 260.0, 25.0)] autorelease];
        self.textFieldEnterDebugArgs.accessibilityLabel = @"AlertDebugArgsField";
        self.textFieldEnterDebugArgs.isAccessibilityElement = YES;
        [self.textFieldEnterDebugArgs setBackgroundColor:[UIColor whiteColor]];
        [self.tabBarController.selectedViewController.view addSubview:self.textFieldEnterDebugArgs];
        [self.tabBarController.selectedViewController.view bringSubviewToFront:self.textFieldEnterDebugArgs];
    }
    else
    {
        if ([self.textFieldEnterDebugArgs.text length] > 0)
        {
            if ([self.textFieldEnterDebugArgs.text hasPrefix:@"http://"])
            {
                [self doDebugHttpRequest:self.textFieldEnterDebugArgs.text];    
            }
        }
    }
}

- (void)requestDidFinishLoad:(TTURLRequest*)request
{
        NSString *response = [[[NSString alloc] initWithData:((TTURLDataResponse*)request.response).data 
                                                    encoding:NSUTF8StringEncoding] autorelease];

        UIAlertView *resultAlert = 
            [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Request Loaded",@"")
                                       message:response
                                      delegate:nil
                             cancelButtonTitle:NSLocalizedString(@"OK",@"")
                             otherButtonTitles:nil] autorelease];
        resultAlert.accessibilityLabel = @"AlertDebugResult";
        [resultAlert show];
}

此代碼將在搖晃后將 UITextField 添加到最頂視圖 controller 上,在任何導航欄或其他 UI 元素的正上方。 UIAutomation 或您的用戶可以手動將 URL 輸入到此 UITextField 中。 當您再次搖動設備時,如果文本以“http”開頭,它將在代碼中發出 HTTP 請求(讀者實現 doDebugHttpRequest 的練習)。

然后,在我的 UIAutomation JavaScript 文件中,我定義了以下兩個函數:

function httpGet(url, delayInSec) {
  if (!delayInSec) delay = 1;
  var alertDebugResultSeen = false;
  var httpResponseValue = null;

  UIATarget.onAlert = function onAlert(alert) {    
    httpResponseValue = alert.staticTexts().toArray()[1].name();
    alert.buttons()[0].tap();
    alertDebugResultSeen = true;
  }

  var target = UIATarget.localTarget();
  var application = target.frontMostApp();
  target.shake(); // bring up the input field
  application.mainWindow().textFields()["AlertDebugArgsField"].setValue(url);
  target.shake(); // send back to be processed
  target.delay(delayInSec);
  assertTrue(alertDebugResultSeen);
  return httpResponseValue;
}

function httpGetJSON(url, delayInSec) {
  var response = httpGet(url, delayInSec);
  return eval('(' + response + ')');
}

現在,在我的 javascript 文件中,我可以調用

httpGet('http://localhost:3000/do_something')

它將執行 HTTP 請求。 如果我想從服務器返回 JSON 數據,我打電話

var jsonResponse = httpGetJSON('http://localhost:3000/do_something')

如果我知道這將是一個長期通話,我會打電話給

var jsonResponse = httpGetJSON('http://localhost:3000/do_something', 10 /* timeout */)

我已經成功使用這種方法幾個星期了。

嘗試performTaskWithPathArgumentsTimeout

UIATarget.host().performTaskWithPathArgumentsTimeout("/usr/bin/curl", "http://google.com", 30);

只是一個小小的修正。 建議使用 UIATarget.host().performTaskWithPathArgumentsTimeout 的答案是在 iOS 5.0+ 中對 URL 發出請求的簡單方法,但該示例的語法不正確。 這是進行此調用的正確方法:

UIATarget.host().performTaskWithPathArgumentsTimeout("/usr/bin/curl", ["http://google.com"], 30);

"args" 參數周圍的 "[" 很重要,如果忘記括號,測試將終止,並出現類似於以下的異常:

錯誤:-[__NSCFString count]:無法識別的選擇器發送到實例

這是一個完整的工作示例,它訪問 google.com 並記錄所有 output:

var result = UIATarget.host().performTaskWithPathArgumentsTimeout("/usr/bin/curl", ["http://www.google.com"], 30);

UIALogger.logDebug("exitCode: " + result.exitCode);

UIALogger.logDebug("stdout: " + result.stdout);

UIALogger.logDebug("stderr: " + result.stderr);

+1 創造性地使用“shake()”。 但是,對於某些項目,尤其是那些實際使用抖動功能的項目,這不是一個選項。

創造性思考。 使用其他東西進行獲取(Python、Ruby、node.js、bash+wget 等)。 然后,您可以通過將動態生成的 json 有效負載作為“樣本數據”包含到測試中,使用預先生成的響應並即時自動生成 ui-test.js。 然后你只需執行測試。

在我看來,測試就是測試,別管它。 您正在使用的測試數據,如果它是動態的,它應該與測試本身分開。 通過以這種方式獲取/生成 JSON,並從測試中引用它,您可以隨時更新 JSON,無論是在每次測試之前,還是在設定的時間間隔內,例如當您知道服務器已更新時。 我不確定您是否希望在測試運行時生成它,這似乎會產生問題。 將其提升到一個新的水平,您可以花哨並使用函數來計算應該基於其他值的值,並將它們公開為數據的“動態屬性”,而不是在測試中進行數學運算,但在那點我認為討論更多的是學術性的,而不是實踐性的。

Apple 最近更新了UIAutomation以包含一個新的UIAHost元素,用於在運行正在執行測試的 Instruments 實例的主機上執行任務

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM