- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 robotium 进行测试,我遇到了一堆计时问题,这些问题让我很难知道 Activity (或 View )何时完成加载。因此,我正在编写的测试不是很可靠。
我正在寻找一种方法,用可以推送到测试框架的事件来检测我的被测应用程序。如果我的被测应用程序可以在预期事件发生时“告诉”我的测试,这将非常有用。我用过 Event Tracing for Windows对于过去的 windows\windows phone 效果很好。
我正在寻找的执行此操作的穷人方法是让我的测试应用程序实时读取 logcat 并在预期事件发生时通知测试。
还有人有其他想法吗?
最佳答案
为了解决这个问题,我依赖操作系统 logcat。我使用跟踪消息检测正在测试的部分代码,并等待它们出现在测试代码中。它可能不是最高效的做事方式,但它适合我的需要。我首先尝试制作一个从 logcat 读取的异步任务,但遇到了计时问题。我终于实现了这样的事情:
logger.info("Click on something");
EmSingleton.get().setCheckPoint();
solo.clickOnText(SOMETHING, 1, true); // writes RELOAD_COMPLETE to logcat when done
logger.info("Validate that the event is done);
EmSingleton.get().waitForEvent(GrouponLnConstants.TodaysDeal.RELOAD_COMPLETE, 15000);
// Do other stuff...
EventManager 代码(我包装在一个名为 EmSingleton 的单例中):
public class EventManager {
private ArrayList<String> args = null;
private long startTime;
public EventManager() {
args = new ArrayList<String>(Arrays.asList("-v", "time", "-d"));
setCheckPoint();
}
public EventManager(ArrayList<String> _args) {
this();
for(String s: args) {
if (!args.contains(s)) {
args.add(s);
}
}
}
public void setCheckPoint()
{
Time startTimeOS = new android.text.format.Time();
startTimeOS.setToNow();
startTime = startTimeOS.toMillis(true);
}
public LogEvent checkEvent(String filter) throws Exception {
ArrayList<LogEvent> events = gatherEvents();
for(LogEvent event: events){
if(event.checkMsgSubstring(filter)){
return event;
}
}
return null;
}
public LogEvent waitForEvent(String filter, int timeout) throws Exception
{
int retries = timeout/1000 == 0 ? 1 : timeout/1000;
for(int i = 0; i < retries; i++)
{
LogEvent event = checkEvent(filter);
if(event != null){
return event;
}
Thread.sleep(1000);
}
return null;
}
public ArrayList<LogEvent> getEvents() {
return gatherEvents();
}
public void clearEvents() throws Exception{
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");
commandLine.add("-c");
ProcessBuilder pb = new ProcessBuilder(commandLine.toArray(new String[0]));
pb.redirectErrorStream(true);
Process logcatProcess = pb.start();
logcatProcess.waitFor();
}
protected ArrayList<LogEvent> gatherEvents() {
ArrayList<LogEvent> events = new ArrayList<LogEvent>();
final StringBuilder log = new StringBuilder();
BufferedReader br;
try {
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");
if (null != args) {
commandLine.addAll(args);
}
ProcessBuilder pb = new ProcessBuilder(commandLine.toArray(new String[0]));
pb.redirectErrorStream(true);
Process logcatProcess = pb.start();
InputStream is = logcatProcess.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = null;
while (true) {
line = br.readLine();
if(line == null){
break;
}
// Add events to the events arraylist if they occur after the LogCollector has started to run
LogEvent event = new LogEvent(line);
if(event.peekTimeMS() > startTime)
{
events.add(event);
}
}
} catch (Exception e) {
TestLogger.get().error("GrouponTest", String.format("gatherEvents doInBackground failed: %s", e.toString()));
}
return events;
}
}
您需要在您的应用程序中设置以下权限:
<uses-permission android:name="android.permission.READ_LOGS">
我还创建了一个 LogEvent 对象来解析来自 logcat 的事件:
public class LogEvent {
String orignalString = null;
boolean parsed = false;
long timeMs = 0;
String timeString = null;
String verbosity = null;
String tag = null;
int pid = 0;
String msg = null;
// Lazy factory design pattern
// http://en.wikipedia.org/wiki/Lazy_initialization
public LogEvent(String s) {
orignalString = s;
}
public long getTimeMs() {
checkInit();
return timeMs;
}
public long peekTimeMS()
{
// Time is always formattted as such: MM-DD HH:MM:SS.XXX
return parseTime(orignalString.substring(0,5), orignalString.substring(6,18));
}
public String getTimeString() {
checkInit();
return timeString;
}
public String getVerbosity() {
checkInit();
return verbosity;
}
public String getTag() {
checkInit();
return tag;
}
public int getPid() {
checkInit();
return pid;
}
public String getMsg() {
checkInit();
return msg;
}
/**
* Checks to see if the event message contains a substring
* @param check
* @return
*/
public Boolean checkMsgSubstring(String check)
{
int index = orignalString.indexOf(check);
boolean isSubstring = (index >= 0);
return isSubstring;
}
public String toString()
{
checkInit();
return String.format("%s %s/%s(%d): %s", timeString, verbosity, tag, pid, msg);
}
private void checkInit()
{
if(!parsed)
{
parseEvent();
parsed = true;
}
}
private void parseEvent()
{
try{
String [] splits = orignalString.split("[ ]+");
// Sometimes the PID is of format ( XX) instead of (XX)
if(splits[2].indexOf(")") < 0)
{
splits[2] += splits[3];
ArrayList<String> formatted = new ArrayList<String>(Arrays.asList(splits));
formatted.remove(3);
splits = formatted.toArray(new String[formatted.size()]);
}
// Parse time
timeMs = parseTime(splits[0], splits[1]);
timeString = String.format("%s %s", splits[0], splits[1]);
// Parse tag
verbosity = parseVerbosity(splits[2]);
tag = parseTag(splits[2]);
pid = parsePid(splits[2]);
// Parse message (may be empty)
if (splits.length > 3) {
msg = orignalString.substring(orignalString.indexOf(splits[3]));
} else {
msg = "";
}
}
catch (Exception e)
{
// TODO: there are some strangely formated events in the system. need to deal with these?
}
}
/**
* Time comes in following format: 08-11 20:03:17.182:
* Parse into milliseconds
* @param day string of format 08-11
* @param hours string of format 20:03:17.182:
* @return
*/
private long parseTime(String day, String hours)
{
Time timeToSet = new Time();
Time currentTime = new Time();
currentTime.setToNow();
// Parse fields
String[] daySplits = day.split("-");
if(daySplits.length < 2)
return 0;
String[] hourSplits = hours.split(":");
if(hourSplits.length < 2)
return 0;
String[] secondSplits = hourSplits[2].split("\\.");
if(secondSplits.length < 2)
return 0;
int _year = currentTime.year;
int _month = Integer.parseInt(daySplits[0])-1;
int _day = Integer.parseInt(daySplits[1]);
int _hour = Integer.parseInt(hourSplits[0]);
int _min = Integer.parseInt(hourSplits[1]);
int _sec = Integer.parseInt(secondSplits[0]);
int _mili = Integer.parseInt(secondSplits[1]);
//set(int second, int minute, int hour, int monthDay, int month, int year)
timeToSet.set(_sec, _min, _hour, _day, _month, _year);
// return calculated value
long parsedTimeInMili = timeToSet.toMillis(true) + (long)_mili;
return parsedTimeInMili;
}
private String parseVerbosity(String s)
{
return s.split("/")[0];
}
private String parseTag(String s)
{
int verbosityLength = parseVerbosity(s).length() +1;
String tagPart = s.substring(verbosityLength);
return tagPart.split("\\(")[0];
}
private int parsePid(String s)
{
try {
String pidPart = s.split("\\(")[1];
return Integer.parseInt(pidPart.split("\\)")[0]);
} catch (Exception e) {
e.toString();
}
return -1;
}
}
关于android - 基于事件的安卓测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7014797/
我正在尝试将 WPF CodeBehid 事件(如 Event、Handler、EventSetter)转换为 MVVM 模式。我不允许使用 System.Windows.Controls,因为我使用
我可能误解了 Backbone 中的事件系统,但是当我尝试以下代码时什么也没有发生。当我向 Backbone.Events 扩展对象添加新属性时,它不应该触发某种更改、更新或重置事件吗?就像模型一样吗
我遇到了一个简单的问题,就是无法弄清楚为什么它不起作用。我有一个子组件“app-buttons”,其中我有一个输入字段,我想听,所以我可以根据输入值过滤列表。 如果我将输入放在我有列表的根组件中,一切
System.Timers.Timer 的 Elapsed 事件实际上与 System.Windows.Forms.Timer 的 Tick 事件相同吗? 在特定情况下使用其中一种比使用另一种有优势吗
嗨,这个 javascript 代码段是什么意思。(evt) 部分是如此令人困惑.. evt 不是 bool 值。这个怎么运作? function checkIt(evt) { evt
我正在使用jquery full calendar我试图在事件被删除时保存它。 $('calendar').fullCalendar ({
我有两个链接的鼠标事件: $('body > form').on("mousedown", function(e){ //Do stuff }).on("mouseup", function(
这是我的代码: $( '#Example' ).on( "keypress", function( keyEvent ) { if ( keyEvent.which != 44 ) {
我尝试了 dragOver 事件处理程序,但它没有正常工作。 我正在研究钢琴,我希望能够弹奏音符,即使那个键上没有发生鼠标按下。 是否有事件处理程序? 下面是我正在制作的钢琴的图片。 最佳答案 您应该
当悬停在相邻文本上时,我需要使隐藏按钮可见。这是通过 onMouseEnter 和 onMouseLeave 事件完成的。但是当点击另外的文本时,我需要使按钮完全可见并停止 onMouseLeave
我有ul标签内 div标签。我申请了mouseup事件 div标记和 click事件 ul标签。 问题 每当我点击 ul标签,然后都是 mouseup和 click事件被触发。 我想要的是当我点击 u
我是 Javascript 和 jQuery 的新手,所以我有一个非常愚蠢的疑问,请耐心等待 $(document).click(function () { alert("!"); v
我有一个邮政编码解析器,我正在使用 keyup 事件处理程序来跟踪输入长度何时达到 5,然后查询服务器以解析邮政编码。但是我想防止脚本被不必要地调用,所以我想知道是否有一种方法可以跟踪 keydown
使用事件 API,我有以下代码来发布带有事件照片的事件 $facebook = new Facebook(array( "appId" => "XXX", "se
首次加载 Microsoft Word 时,既不会触发 NewDocument 事件也不会触发 DocumentOpen 事件。当 Word 实例已打开并打开新文档或现有文档时,这些事件会正常触发。
我发现了很多相关问题(这里和其他地方),但还没有具体找到这个问题。 我正在尝试监听箭头键 (37-40) 的按键事件,但是当以特定顺序使用箭头键时,后续箭头不会生成“按键”事件。 例子: http:/
给定的 HTML: 和 JavaScript 的: var $test = $('#test'); $test.on('keydown', function(event) { if (eve
我是 Node.js 的新手,希望使用流运行程序。对于其他程序,我必须同时启动一个服务器(mongodb、redis 等),但我不知道我是否应该用这个运行一个服务器。请让我知道我哪里出了问题以及如何纠
我正在尝试使用 Swift 和 Cocoa 创建一个适用于 OS X 的应用程序。我希望应用程序能够响应关键事件,而不将焦点放在文本字段上/文本字段中。我在 Xcode 中创建了一个带有 Storyb
我有以下代码: (function(w,d,s,l,i){ w[l]=w[l]||[];w[l].push({
我是一名优秀的程序员,十分优秀!