Add tools for converting the performance tests data to excel files.

This commit is contained in:
zhangbin 2015-09-14 09:52:21 +08:00
parent edb964a673
commit 5d47ce8f23
3 changed files with 276 additions and 8 deletions

View File

@ -6,7 +6,7 @@
#include "cocos2d.h" #include "cocos2d.h"
#include <time.h> #include <time.h>
#define LOG_FILE_NAME "PerformanceLog.json" #define LOG_FILE_NAME_FMT "PerformanceLog-%s-%s.json"
#define PLIST_FILE_NAME "PerformanceLog.plist" #define PLIST_FILE_NAME "PerformanceLog.plist"
#define KEY_DEVICE "device" #define KEY_DEVICE "device"
@ -20,14 +20,14 @@
#define FILE_VERSION 1 #define FILE_VERSION 1
#define USE_PRETTY_OUTPUT_FORMAT 1 #define USE_PRETTY_OUTPUT_FORMAT 0
#define USE_JSON_FORMAT 1 #define USE_JSON_FORMAT 1
// For different device & os, change these values // For different device & os, change these values
// TODO : get device info automatically // TODO : get device info automatically
#define DEVICE_NAME "iphone 5s" #define DEVICE_NAME "DeviceName"
#define OS_VERSION "iOS 8.4" #define OS_VERSION "SystemVersion"
static Profile* s_profile = nullptr; static Profile* s_profile = nullptr;
@ -223,10 +223,13 @@ void Profile::flush()
testData[KEY_TIMESTAMP] = Value(genStr("%ld", t)); testData[KEY_TIMESTAMP] = Value(genStr("%ld", t));
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
std::string checkPath = "/mnt/sdcard"; std::string checkPath = "/mnt/sdcard/PerfTest";
auto writablePath = checkPath; auto writablePath = checkPath;
if (! cocos2d::FileUtils::getInstance()->isDirectoryExist(checkPath)) { if (! cocos2d::FileUtils::getInstance()->isDirectoryExist(checkPath)) {
writablePath = cocos2d::FileUtils::getInstance()->getWritablePath(); auto createRet = cocos2d::FileUtils::getInstance()->createDirectory(checkPath);
if (! createRet) {
writablePath = cocos2d::FileUtils::getInstance()->getWritablePath();
}
} }
cocos2d::log("write path : %s", writablePath.c_str()); cocos2d::log("write path : %s", writablePath.c_str());
#else #else
@ -234,8 +237,11 @@ void Profile::flush()
#endif #endif
#if USE_JSON_FORMAT #if USE_JSON_FORMAT
std::string fullPath = genStr("%s/%s", writablePath.c_str(), LOG_FILE_NAME); char timeStr[64];
strftime(timeStr, sizeof(timeStr), "%Y-%m-%d-%H%M", localtime(&t));
std::string fileName = genStr(LOG_FILE_NAME_FMT, DEVICE_NAME, timeStr);
std::string fullPath = genStr("%s/%s", writablePath.c_str(), fileName.c_str());
rapidjson::Document document; rapidjson::Document document;
rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value theData = valueMapToJson(testData, allocator); rapidjson::Value theData = valueMapToJson(testData, allocator);

View File

@ -0,0 +1,107 @@
# Performance Test Data Convertor
## Overview
Performance Test Data Convertor is used for converting the json files to excel files. The json files are generated from project `tests/performance-tests`.
## Requirement
* Python 2.7 is required. (Python 2.7.5 is well tested)
* [xlwt](https://pypi.python.org/pypi/xlwt/) for python to write excel files.
## Generate test data
1. Change the device name in the tests source code.
Now you should modify the device name in `tests/performance-tests/Classes/Profile.cpp` before running the tests. Sample code:
```
// For different device & os, change these values
// TODO : get device info automatically
#define DEVICE_NAME "TheDeviceName"
#define OS_VERSION "SystemVersion"
```
2. Run the performance-tests project on devices.
Once the project started, you will see a scene like this:
![test-scene][test-scene.jpg]
3. Click the menu `Start AutoTest`. Then the performance tests will running automatically. Once the scene stopped at the scene again. It's mean the autotesting is end.
## Get the generated json files
After the test data generated, you can get the json file from the device.
The json file will be named with format : `PerformanceLog-[DEVICE_NAME]-[TIMESTAMP].json`.
For different OS, you can get the json files by different steps:
### From iOS devices
The json files will generated in the `Document` folder of the app. So you can get the json files by iTunes by steps:
![itunes][itunes.jpg]
### From Android devices
The json files will be generated in the path `/mnt/sdcard/PerfTest`. So you can get the json files by commands like this:
* Windows System
Run the command in cmd:
```
%ANDROID_SDK_ROOT%\platform-tools\adb pull /mnt/sdcard/PerfTest C:\Users\USER_NAME\MY_LOG_FOLDER
```
* Mac System
Run the command in terminal:
```
$ANDROID_SDK_ROOT/platform-tools/adb pull /mnt/sdcard/PerfTest ~/MY_LOG_FOLDER
```
### From Mac devices
The json files will be generated in the path `~/Document`.
### From Win32 devices
The json files will be generated in the AppData path. For different system versions, it will be different path.
The path will be `C:\Users\USER_NAME\AppData\Local\performance-tests` on Win8.1.
## Convert json files to excel files
When the json files are ready, you can convert the json files to excel files by `tools/performance-analyze/convertor.py`.
The usage of the tool:
```
usage: convertor.py [-h] -s SRC_PATH [-o OUTPUT_PATH]
Performance test data convertor.
optional arguments:
-h, --help show this help message and exit
-s SRC_PATH Specify the json file path or the folder path of json files.
-o OUTPUT_PATH Specify the output path of excel files.
```
Tips:
* The value of `-s` can be a json file or a folder which contains many json files. If it's a folder, then the json files in the folder will be converted to excel files one by one.
* You can specify the output path by `-o`. If it's not specified, the excel files will be placed in the same folder of json files.
* Each json file will generate an excel file. The excel file name will be same with the json file. For example:
`python convertor.py -s PerformanceLog-iphone4s-2015-09-11-1745.json` will generate a `PerformanceLog-iphone4s-2015-09-11-1745.xls` file.
* The format of the excel file will be looks like this:
![excel format][excel.jpg]
1. Each sheet shows the result of a test case.
2. The cells with GREEN background color are the conditions of the test case.
3. The cells with YELLOW background color are the result data of the test case.
[test-scene.jpg]: http://i60.tinypic.com/ou86bs.jpg
[itunes.jpg]: http://i60.tinypic.com/33z4r53.jpg
[excel.jpg]: http://i57.tinypic.com/wvx500.jpg

View File

@ -0,0 +1,155 @@
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# ----------------------------------------------------------------------------
# Convert the performance test result from json files to excel.
#
# Author: Bill Zhang
#
# License: MIT
# ----------------------------------------------------------------------------
'''
Convert the performance test result from json files to excel.
'''
import xlwt
import os
import json
from argparse import ArgumentParser
DEFAULT_STYLE = 'borders: left thin, right thin, top thin, bottom thin;'
CONDITION_STYLE = 'pattern: pattern solid, fore_color light_green;'
RESULT_STYLE = 'pattern: pattern solid, fore_color light_yellow;'
BASE_KEYS = [
'osVersion',
'fileVersion',
'timeStamp',
'engineVersion',
'device'
]
KEY_CONDITION_HEADERS = "conditionHeaders"
KEY_RESULT_HEADERS = "resultHeaders"
KEY_RESULTS = "results"
START_COL_INDEX = 0
START_ROW_INDEX = 0
class KnownException(Exception):
pass
class Convertor:
def __init__(self, src_path, output_path=None):
self.src_path = self.change_to_abspath(src_path)
if not os.path.exists(self.src_path):
raise KnownException('%s is not existed!' % self.src_path)
if output_path is None:
# not specified output path, default use source path
if os.path.isfile(self.src_path):
self.output_path = os.path.dirname(self.src_path)
else:
self.output_path = self.src_path
else:
self.output_path = self.change_to_abspath(output_path)
def change_to_abspath(self, path):
ret = os.path.expanduser(path)
if not os.path.isabs(ret):
ret = os.path.abspath(ret)
ret = os.path.normpath(ret)
return ret
def get_col_width(self, col_str):
return 256 * (len(col_str) + 1)
def convert_file(self, file_path):
f = open(file_path)
testData = json.load(f)
f.close()
basename, ext = os.path.splitext(os.path.basename(file_path))
dst_file_path = os.path.join(self.output_path, "%s.xls" % basename)
if os.path.isfile(dst_file_path):
os.remove(dst_file_path)
workbook = xlwt.Workbook(encoding = 'ascii')
default_style = xlwt.Style.easyxf(DEFAULT_STYLE)
con_style = xlwt.Style.easyxf("%s%s" % (DEFAULT_STYLE, CONDITION_STYLE))
ret_style = xlwt.Style.easyxf("%s%s" % (DEFAULT_STYLE, RESULT_STYLE))
for key in testData.keys():
if key in BASE_KEYS:
continue
# create a sheet for the test case
sheetObj = workbook.add_sheet(key)
# get test case data
caseInfo = testData[key]
# Add headers for the test case
condHeaders = caseInfo[KEY_CONDITION_HEADERS]
retHeaders = caseInfo[KEY_RESULT_HEADERS]
curRow = START_ROW_INDEX
curCol = START_COL_INDEX
col_widths = {}
for header in (condHeaders + retHeaders):
sheetObj.write(curRow, curCol, header, default_style)
col_width = self.get_col_width(header)
col_widths[curCol] = col_width
sheetObj.col(curCol).width = col_width
curCol += 1
rets = caseInfo[KEY_RESULTS]
for retInfo in rets:
curRow += 1
curCol = START_COL_INDEX
for ret in retInfo:
if (curCol - START_COL_INDEX) < len(condHeaders):
use_style = con_style
else:
use_style = ret_style
sheetObj.write(curRow, curCol, ret, use_style)
new_width = self.get_col_width(ret)
old_width = col_widths[curCol]
if new_width > old_width:
sheetObj.col(curCol).width = new_width
col_widths[curCol] = new_width
curCol += 1
workbook.save(dst_file_path)
print("%s is generated." % dst_file_path)
def do_convert(self):
if not os.path.exists(self.output_path):
os.makedirs(self.output_path)
if os.path.isfile(self.src_path):
self.convert_file(self.src_path)
else:
for f in os.listdir(self.src_path):
full_path = os.path.join(self.src_path, f)
ignore, ext = os.path.splitext(f)
if os.path.isfile(full_path) and ext == '.json':
self.convert_file(full_path)
if __name__ == '__main__':
parser = ArgumentParser(description="Performance test data convertor.")
parser.add_argument('-s', dest='src_path', required=True, help='Specify the json file path or the folder path of json files.')
parser.add_argument('-o', dest='output_path', help='Specify the output path of excel files.')
(args, unknown) = parser.parse_known_args()
try:
convertor = Convertor(args.src_path, args.output_path)
convertor.do_convert()
except Exception as e:
if e.__class__.__name__ == "KnownException":
print(' '.join(e.args))
else:
raise