通過instruments針對IOS壓力測試研究總結

運行環境:

1,環境iMac OS X 10.9.5

2,工具Xcode Version 6.1 (6A1052c)

3,簽約證書(開發者提供)

4,iphone設備(系統IOS6、IOS7、IOS8.1)

UI AUtoMonkey是一款非常簡單的IOS壓力測試工具。通過它,你可以向ios設備發送滑動、拖動、旋轉、甚至鎖屏和解鎖指令。原文github地址:https://github.com/jonathanpenn/ui-auto-monkey

首先,使用xcode打開你的ios項目,從“Product”菜單中選擇“Profile”(或者直接快捷鍵Command+i),這樣就可以構建ios項目,並啓動工具模板選擇器。

            下一步,在選擇器中選擇“UI Automation”當我們創建了自動化模板後,就可以測試app的性能了。

            Scripts面板中,點擊“Editor Log”,在下拉列表中選擇“Script”,點擊“Add”按鈕,在下拉列表中選擇”Create”,就可以新建一個js腳本。


            UIAutoMonkey.js這個文件的內容粘貼到新建的js腳本中(或者可以直接將UIAutoMonkey.jsimport進去。

              此時,我們可以直接點擊播放按鈕,來執行這段腳本,monkey測試就開始了。

源碼:"use strict";


function UIAutoMonkey() {
    
    
    
    this.config = {
        
    numberOfEvents: 1000,           //產生隨機事件的個數
        
    delayBetweenEvents: 0.05,    // 事件之間的延遲時間

        
        // If the following line is uncommented, then screenshots are taken
        
        // every "n" seconds.
        
        //screenshotInterval: 5,
        

        
        // Events are triggered based on the relative weights here. The event
        
        // with this highest number gets triggered the most.
        
        //
        
        // If you want to add your own "events", check out the event method
        
        // definitions below.
        
    eventWeights: {                 //每個事件的觸發機率,如果tab事件的值爲100、orientation事件的值爲1,那麼tab事件觸發的機率就是orientation的100倍。
        
    tap: 500,
        
    drag: 1,            //拖
        
    flick: 1,           //輕擊
        
    orientation: 1, //定位
        
    clickVolumeUp: 1,
        
    clickVolumeDown: 1,
        
    lock: 1,
        
    pinchClose: 10,     //捏
        
    pinchOpen: 10,
        
    shake: 1            //動搖
        
    },

        // Probability that touch events will have these different properties
        
    touchProbability: {     //控制着不同種類的tab事件
        
    multipleTaps: 0.05,
        
    multipleTouches: 0.05,
        
    longPress: 0.05
        
    }
        

        
        // Uncomment the following to restrict events to a rectangluar area of
        
        // the screen
        
       
       /*
         frame: {
         
         origin: {x: 0, y: 0},
         
         size: {width: 320, height: 480}
         
         }
       */
        

        
    };
    
    
    
}


// Event Methods


// Any event probability in the hash above corresponds to a related event


// method below. So, a "tap" probability will trigger a "tap" method.


//


// If you want to add your own events, just add a probability to the hash


// above and then add a corresponding method below. Boom!



// Each event method can call any other method on this UIAutoMonkey object.


// All the methods at the end are helpers at your disposal and feel free to


// add your own.


UIAutoMonkey.prototype.allEvents = {
    
tap: function() {
    
    this.target().tapWithOptions(
                                 
                                 { x: this.randomX(), y: this.randomY() },
                                 
                                 {
                                 
                                 tapCount: this.randomTapCount(),
                                 
                                 touchCount: this.randomTouchCount(),
                                 
                                 duration: this.randomTapDuration()
                                 
                                 }
                                 
                                 );
    
},
    

drag: function() {
    
    this.target().dragFromToForDuration(
                                        
                                        { x: this.randomX(), y: this.randomY() },
                                        
                                        { x: this.randomX(), y: this.randomY() },
                                        
                                        0.5
                                        
                                        );
    
},
    

flick: function() {
    
    this.target().flickFromTo(
                              
                              { x: this.randomX(), y: this.randomY() },
                              
                              { x: this.randomX(), y: this.randomY() }
                              
                              );
    
},
    

orientation: function() {
    
    var orientations = [
                        
                        UIA_DEVICE_ORIENTATION_PORTRAIT,
                        
                        UIA_DEVICE_ORIENTATION_PORTRAIT_UPSIDEDOWN,
                        
                        UIA_DEVICE_ORIENTATION_LANDSCAPELEFT,
                        
                        UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT
                        
                        ];
    
    
    
    
    var i = Math.floor(Math.random() * 10) % orientations.length;
    
    var newOrientation = orientations[i];
    
    this.target().setDeviceOrientation(newOrientation);
    
    this.delay(0.9);
    
},
    

clickVolumeUp: function() {
    
    this.target().clickVolumeUp();
    
},
    
    
    
    
clickVolumeDown: function() {
    
    this.target().clickVolumeUp();
    
},

lock: function() {
    
    this.target().lockForDuration(Math.random() * 3);
    
},
    
    
    
    
pinchClose: function () {
    
    this.target().pinchCloseFromToForDuration(
                                              
                                              { x: this.randomX(), y: this.randomY() },
                                              
                                              { x: this.randomX(), y: this.randomY() },
                                              
                                              0.5
                                              
                                              );
    
},
    
    
    
    
pinchOpen: function () {
    
    this.target().pinchOpenFromToForDuration(
                                             
                                             { x: this.randomX(), y: this.randomY() },
                                             
                                             { x: this.randomX(), y: this.randomY() },
                                             
                                             0.5
                                             
                                             );
    
},
    
    
    
    
shake: function() { //搖
    
    this.target().shake();
    
}
    
};


// --- --- --- ---


// Helper methods



UIAutoMonkey.prototype.RELEASE_THE_MONKEY = function() {
    
    // Called at the bottom of this script to, you know...
    
    //
    
    // RELEASE THE MONKEY!
    
    
    
    
    for(var i = 0; i < this.config.numberOfEvents; i++) {
        
        this.triggerRandomEvent();
        
        if (this.config.screenshotInterval) this.takeScreenShotIfItIsTime();
        
        this.delay();
        
    }
    
};



UIAutoMonkey.prototype.triggerRandomEvent = function() {
    
    var name = this.chooseEventName();
    
    // Find the event method based on the name of the event
    
    var event = this.allEvents[name];
    
    event.apply(this);
    
};



UIAutoMonkey.prototype.target = function() {
    
    // Return the local target.
    
    return UIATarget.localTarget();
    
};


UIAutoMonkey.prototype.delay = function(seconds) {
    
    // Delay the target by `seconds` (can be a fraction)
    
    // Defaults to setting in configuration
    
    seconds = seconds || this.config.delayBetweenEvents;
    
    this.target().delay(seconds);
    
};


UIAutoMonkey.prototype.chooseEventName = function() {
    
    // Randomly chooses an event name from the `eventsWeight` dictionary
    
    // based on the given weights.
    
    var calculatedEventWeights = [];
    
    var totalWeight = 0;
    
    var events = this.config.eventWeights;
    
    for (var event in events) {
        
        if (events.hasOwnProperty(event)) {
            
            calculatedEventWeights.push({
                                        
                                        weight: events[event]+totalWeight,
                                        
                                        event: event
                                        
                                        });
            
            totalWeight += events[event];
            
        }
        
    }
    

    
    var chosenWeight = Math.random() * 1000 % totalWeight;
    
    
    
    
    for (var i = 0; i < calculatedEventWeights.length; i++) {
        
        if (chosenWeight < calculatedEventWeights[i].weight) {
            
            return calculatedEventWeights[i].event;
            
        }
        
    }
    

    throw "No even was chosen!";
    
};


UIAutoMonkey.prototype.screenWidth = function() {
    
    // Need to adjust by one to stay within rectangle
    
    return this.target().rect().size.width - 1;
    
};



UIAutoMonkey.prototype.screenHeight = function() {
    
    // Need to adjust by one to stay within rectangle
    
    return this.target().rect().size.height - 1;
    
};



UIAutoMonkey.prototype.randomX = function() {
    
    var min, max;
    
    
    
    
    if (this.config.frame){
        
        // Limits coordinates to given frame if set in config
        
        min = this.config.frame.origin.x;
        
        max = this.config.frame.size.width + min;
        
    } else {
        
        // Returns a random X coordinate within the screen rectangle
        
        min = 0;
        
        max = this.screenWidth();
        
    }
    
 
    return Math.floor(Math.random() * (max - min) + min) + 1;
    
};


UIAutoMonkey.prototype.randomY = function() {
    
    var min, max;
    
    
    
    
    if (this.config.frame){
        
        // Limits coordinates to given frame if set in config
        
        min = this.config.frame.origin.y;
        
        max = this.config.frame.size.height + min;
        
    } else {
        
        // Returns a random Y coordinate within the screen rectangle
        
        min = 0;
        
        max = this.screenHeight();
        
    }
    

    return Math.floor(Math.random() * (max - min) + min) + 1;
    
};


UIAutoMonkey.prototype.randomTapCount = function() {
    
    // Calculates a tap count for tap events based on touch probabilities
    
    if (this.config.touchProbability.multipleTaps > Math.random()) {
        
        return Math.floor(Math.random() * 10) % 3 + 1;
        
    }
    
    else return 1;
    
};

UIAutoMonkey.prototype.randomTouchCount = function() {
    
    // Calculates a touch count for tap events based on touch probabilities
    
    if (this.config.touchProbability.multipleTouches > Math.random()) {
        
        return Math.floor(Math.random() * 10) % 3 + 1;
        
    }
    
    else return 1;
    
};


UIAutoMonkey.prototype.randomTapDuration = function() {
    
    // Calculates whether or not a tap should be a long press based on
    
    // touch probabilities
    
    if (this.config.touchProbability.longPress > Math.random()) {
        
        return 0.5;
        
    }
    
    else return 0;
    
};



UIAutoMonkey.prototype.randomRadians = function() {
    
    // Returns a random radian value
    
    return Math.random() * 10 % (3.14159 * 2);
    
};


UIAutoMonkey.prototype.takeScreenShotIfItIsTime = function() {
    
    var now = (new Date()).valueOf();
    
    if (!this._lastScreenshotTime) this._lastScreenshotTime = 0;

    
    if (now - this._lastScreenshotTime > this.config.screenshotInterval * 1000) {
        
        var filename = "monkey-" + (new Date()).toISOString().replace(/[:\.]+/g, "-");
        
        this.target().captureScreenWithName(filename);
        
        this._lastScreenshotTime = now;
        
    }
    
};


// Commodity function to call RELEASE_THE_MONKEY directly on UIAutoMonkey


// if you don't need to customize your instance


UIAutoMonkey.RELEASE_THE_MONKEY = function() {
    
    (new UIAutoMonkey()).RELEASE_THE_MONKEY();
    
};


UIAutoMonkey.RELEASE_THE_MONKEY();


Note: The Automation instrument works only with apps that have been code signed with a development provisioning profile when they are built in Xcode. Apps signed with a distribution provisioning profile cannot be controlled with the UI Automation programming interface. However, because scripts run outside your app, the app version you are testing can be the same one you submit to the App Store, as long as you rebuild it with the distribution profile.

Important: Simulated actions may not prevent your test device from auto-locking. To ensure that auto-locking does not happen, before running tests on a device, you should set the Auto-Lock setting to Never.

iOS 8 Enhancement: iOS 8 includes a new Enable UI Automation preference under Settings > Developer, which allows third-party developers finer control of when their devices are available to perform automation. For physical iOS devices, this setting is off by default and must be enabled prior to performing any UI Automation. In the simulator, the setting is enabled by default.


更多Instruments用法參考:

https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html#//apple_ref/doc/uid/TP40004652-CH20-SW1


Contact

Jonathan Penn

http://cocoamanifest.net

License

UIAutoMonkeyis available under the MIT license. See the LICENSE file for more info.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章