发布新日志

  • loadruner vugen 回放返回 :Fatal Error -26499

    2016-08-06 21:27:29

    Loadrunner vugen回放的时候返回下面的错误码:
    Fatal Error -26499: Internal Error - mptVUserVars->_hDfePE is unexpectedly NOT NULL after xfeLrwSrvNetTaskItemPrimaryCreate. Is it a concurrent group?

    原因是我录制的脚本中,报错地方前面有一对
     web_concurrent_start 
    web_concurrent_end 
    函数:
    函数可以
    // 标记并发组的开始。组中的所有函数均并发执行。组的结束由函数
    // web_concurrent_end 标记。在并发组中可以包含操作函数和几个服务函数。


    解决上面问题的办法就是:把这一对并发组函数注释掉
  • Vugen运行的时候提示“服务器正在运行中”

    2016-03-17 16:23:24

    Vugen运行的时候弹出提示框“服务器正在运行中”

    百度了下找到的答案是,在进程中找到“ThumbProcess.exe”进程,关闭,再重新运行就好了。
  • appium默认60秒关闭应用的问题

    2016-03-09 16:04:54

    问题:appium默认启动一个应用的session过期时间是60秒到时间会自动停了刚启动的应用,工作台打印:info: [debug] We shut down because no new commands came in的日志
         
    分析:--command-timeout  60 The default command timeout for the server to use for all sessions (in seconds and should be less than 2147483). Will still be overridden by newCommandTimeout cap
    意思是默认60秒过期,超过60秒就会自动


    解决办法:
    从appium工作台最前面找到,启动命令:
    > Launching Appium server with command: C:\Program Files (x86)\Appium\node.exe lib\server\main.js --address 127.0.0.1 --port 4723 --avd Nexus7 --platform-name Android --platform-version 19 --automation-name Appium --device-name "Android Emulator" --log-no-color

    在cmd命令行,对应目录加时间参数即可:--command-timeout 600
    在目录:C:\Program Files (x86)\Appium>
    执行
    node.exe node_modules\appium\lib\server\main.js --
    address 127.0.0.1 --port 4723 --avd Android4.4.2 --device-ready-timeout 70 --pla
    tform-name Android --platform-version 19 --automation-name Appium --avd Nexus7 -
    -device-name "Android Emulator" --log-no-color --command-timeout 600

    启动日志中就能看到:
    info: [debug] Non-default server args: {"address":"127.0.0.1","logNoColors":true
    ,"avd":"Nexus7","androidDeviceReadyTimeout":"70","deviceName":"Android Emulator"
    ,"platformName":"Android","platformVersion":"19","automationName":"Appium","defa
    ultCommandTimeout":600}
    时间变成600秒了
  • LR11使用代理录制手机脚本

    2016-02-19 14:44:29

    LR11使用代理录制手机APP脚本,很常用,不过我看了好久都没弄成功,今天终于成功了,记录一下。

    资源配置:
    操作系统:win7;软件:fiddler(抓包工具,用来做http代理用);Loadrunner11;手机一部(我用的是华为荣耀6plus)

    步骤:
    1、关闭了防火墙,360等东西(这个是为了以防万一,我提前关闭的,下面的操作不知道跟这个有没关系);
    2、设置fiddler端口号是8888;启动fiddler,保证fiddler能抓到电脑上浏览器的http的包就行了;
    3、启动LR的vugen
    4、新建web(http/html)协议的脚本;
    5、Start Recording设置:
       Application type:Win32 Applications
       Program to record:D:\Program Files (x86)\HP\LoadRunner\bin\wplus_init_wsock.exe
       Program arguments:空
       Working directory:D:\Program Files (x86)\HP\LoadRunner\bin(其实就是wplus_init_wsock.exe的所在目录名称);
       Record into Action:Action(这是默认的)
    6、Start Recording-点击Options...准备配代理
       Recording Options--Network-Port Mapping:
          Capture level:Socket level data
          下面就是代理的配置了:(点击New Entry进入Server Entry页面配置)
              Target Server:192.168.1.107(本机IP)
              Port:8888(fiddler上的端口)
              勾选:Allow forwarding to target server from local port 端口号写:9988(这个端口号是手机链接代理使用端口号,我就是一直没弄明白这个端口号的作用浪费了2天时间)
    在Network:Port Mapping页面看到新增的代理,就说明代理配置成功了。
    7、点击Start Recording窗口上的”OK“开始录制吧。
    8、配置手机wifi:
        代理:手动
        代理服务器主机名:192.168.1.107(lr所在电脑IP)
        代理服务器端口:9988(lr中配的那个端口号)
       连接wifi
    9、在手机上启动要录制的APP,进行操作

          
  • 用Jmeter录制手机app脚本

    2016-02-18 16:14:25

    今天看到一个51的朋友发的使用Jmeter录制手机APP的介绍,实践了一下,在这里记录一下,以防忘记了。
    准备:
    电脑装了Jmeter;手机;公司的wifi;
    操作步骤:
    1、启动Jmeter
    2、“测试计划”中添加“线程组”;
    3、“工作台”中添加“HTTP代理服务器”;
    4、配置代理服务器:Global Settings下面的端口配置:9988,HTTPS Domains配置:http://192.168.1.107
    5、HTTP代理服务器--点击“启动”按钮,启动HTTP代理服务器;
    6、手机上配置wifi-“修改网络”设置如下(后面的附图里也有这个设置)
       “代理”---选择“手动”;
       “代理服务器主机名”---“192.168.1.107
       “代理服务器端口”----“9988
    7、可能IE也要设置一下:(这个我不确定,只是刚才关了jmeter的时候不能上网了来IE上去掉这个代理才行)
       IE选项--连接--局域网设置--为LAN使用代理服务器前选中--高级(http:127.0.0.1;端口:9988)
    8、手机连接刚才配置的wifi;(一般这个时候连成功,线程组下面就能看到抓到很多请求了)
    9、启动手机上需要测试的APP,进行业务操作;(这个时候可以看到线程组抓到**P上发出的请求了)
    10、业务操作完毕,立即关闭jemter上的“HTTP代理服务器”(要不一直抓没用的包到线程组了);
    11、在“线程组”删除无关的请求;
    12、保存jmx脚本;
    13、回放。

    后面就是jmeter的参数化之类的操作了
  • python如何调用chrome浏览器

    2016-01-14 18:12:08

    python+selenium浏览器调用(chrome、ie、firefox)

    代码:

    复制代码
    #coding=utf-8
    
    
    from selenium import webdriver
    
    driver=webdriver.Chrome()  #调用chrome浏览器
    
    driver.get('https://www.baidu.com')
    
    print driver.title
    
    driver.quit()


    ------------------------------------------------------------------------------
    如果调用其他浏览器,代码换下即可:

    driver=webdriver.Ie()   #调用ie浏览器
    
    driver=webdriver.Firefox()  #调用firefox浏览器
     
    复制代码

    1 在chrome 下运行脚本,需要将chromedriver.exe 放在chrome浏览器安装目录下

    (同时设置用户环境变量path:C:\Users\xxxxxx\AppData\Local\Google\Chrome\Application;)

    2 在ie 下运行脚本,需要将IEDriverServer.exe 放在ie浏览器安装目录下

    (同时设置用户环境变量path:C:\Program Files\Internet Explorer )

    3 在firefox下运行脚本,直接调用(默认安装路径下)

    总结:调用chrome、ie浏览器需要提前把对应的driver下载好,并放到安装目录下,同时设置好环境变量


  • loadrunner Capture level设置原理

    2016-01-06 16:48:45

    首先写一下LR帮助文档中的解释:
    The level of data to capture (relevant only for HTTP based protocols):
    • Socket level data. Capture data using trapping on the socket level only. Port mappings apply in this case (default).
    • WinINet level data. Capture data using hooks on the WinINet.dll API used by certain HTTP applications. The most common application that uses these hooks is Internet Explorer. Port mappings are not relevant for this level.
    • Socket level and WinINet level data. Captures data using both mechanisms. WinINet level sends information for applications that use WinINet.dll. Socket level sends data only if it determines that it did not originate from WinINet.dll. Port mapping applies to data that did not originate from WinINet.dll.

    • 我自己理解是这么的:
      socket level data是使用socket协议,直接监听端口抓取数据。                                                   winINet level data是启用WinInet.dll在协议层抓取数据,我看了下“勾子”原理,好像是另外起一个应用来完成抓取的工作,不用监听端口;(http://www.cnblogs.com/cryinstall/archive/2011/08/30/2280826.html这个URL介绍了勾子技术)    socket level and winINet level data是使用了上面2中技术;当有端口的时候就使用socket抓取当没有明确的端口的时候就是用winINet抓取。                                                                                                                                                                                                                                                                                                                             其实还有一个地方Network-level server address mappings for:z还有当选中socket抓取的时候才能选择下面的协议,我估计就是因为下面的协议都是有端口的。而使用WinINet的时候这个就不能选了,因为这种抓取技术跟端口没关系了。                                                                                                                                                                                                             所以我们平常抓取http协议的时候只要选socket就好了,如果碰到https的时候再选择WinINet.
  • 安装的seleniumIDE在firefox工具栏看不到图标怎么办

    2016-01-06 11:21:07

    出现上面的原因是:安装的seleniumIDE在firefox中被禁用了

    解决办法:(重启开启被禁用的组件即可),操作步骤:
    1、在firefox新标签中输入about:config;
    2、搜索“xpinstall.signatures.required”,右键,点击“切换”
    看到“值”变成了“false”
    3、重启firefox
    这下就能看到“工具---seleniumIDE”了

    firefox自带的帮助信息是这么写的:

    强制禁用这个首选项(高级用户): 你可以在 Firefox 配置编辑页面about:config 页面)把 xpinstall.signatures.required 首选项设为 false 来强制禁用附加组件验证的功能。我们不会为手动在配置编辑页面做出的任何修改提供援助,因此请自担风险。



  • loadrunner转码函数的学习

    2016-01-05 16:37:13

    Action()
    {    //转码测试
    /*
        int lr_convert_string_encoding( const char *sourceString, const char *fromEncoding, const char *toEncoding, const char *paramName); 
        sourceString  The string to convert  需要转换的字符
        fromEncoding  The encoding of the sourceString  原来字符的编码
        toEncoding  The encoding to convert of the string saved in parameter paramName  需要转换成的编码  
        paramName  The name of the parameter in which the destination string will be saved   保存转码后的字符的变量名称

        */
         lr_start_transaction("convert");

    lr_convert_string_encoding(lr_eval_string("智能手机"),"gb2312","utf-8","a1");//把智能手机编码从gb2312转成utf-8,放在a1中,在函数中使用的时候直接{a1}使用就可以了

    lr_convert_string_encoding(lr_eval_string("{a1}"),"utf-8","gb2312","bb");//把刚才转码的再转一次还原,给下面的语句来打印它

    lr_output_message(lr_eval_string("{bb}"));

    lr_end_transaction("convert",LR_AUTO);

    return 0;
    }
  • loadrunner学习记录及问题.doc

    2011-06-22 11:15:09

    2011-05-27

    1、《loadrunner虚拟用户开发指南》

    2Vuser中常用的C语言函数:

       1.strchrstrrchr

         Strchr函数用于查找指定字符在一个字符串中第一次出现的位置,然后返回指向该位置的指针。Char *strchr (const char *string,int c);

         Strrchrstrchr类同只是查询的是指定字符在字符串中最后出现的位置,然后返回指向该位置的指针 char *strrchr(const char *string ,int c);

         Example:

          char *string="I'm a young soul in this very strange world.";

          char *first_a,*last_a;

     

          first_a=(char *)strchr(string,'a');

          lr_output_message("first occurrence of a:%s",first_a);

           //first occurrence of a:a young soul in this very strange world.

          last_a=(char *)strrchr(string,'a');

          lr_output_message("The last occurrence of a:%s",last_a);

          //The last occurrence of a:ange world.

    2.strcpystrncpy

      Strcpy把一个字符串复制到另一个字符串中;strncpy是把一个字符串的指定长度字符复制到另一个字符串中。

      Char *strcpy(char *dest,const char *source);

      Char *strncpy(char *dest,const char *source,size_t n);

      Example:

        char test[50];

        char ntest[50];

        strcpy(test,"Copies one string to another.");

        lr_output_message("test=%s",test);

        //test=Copies one string to another.

        strncpy(ntest,"Copies the first n characters of one string to another?",30);

        lr_output_message("ntest=%s",ntest);

        //ntest=Copies the first n characters

    3.strcmpstricmp

      用与按照字母表顺序比较2个字符串的大小;前者比较时区分字符串大小写;后者比较时不区分字符串大小写

      Int strcmp(const char *string1,const char *string2);

      Int stricmp(const char *string1,const char *string2)

      Example:

        char *string1="This ABCDEFG";

        char *string2="This abcdefg";

        int result;

        result=strcmp(string1,string2);

        lr_output_message("strcmp result=%d",result);

        //strcmp result=-1

     

        result=stricmp(string1,string2);

        lr_output_message("stricmp result=%d",result);

        //stricmp result=0

    4.strcatstrncat

      Strcat是把一个字符串复制到另一个字符串的后面,strncat是把一个字符串的指定长度字符串复制到另一个字符串的后面。

    5.sprintf

      Sprintf是把一个字符串格式化后输入到另一个字符串中,然后返回写入的字符数量。

      Int sprintf(char *string,const char *format_string[,args]);

      String 是要写入的目标字符串,format_string是格式化的字符串,args是一系列变量表达式

      Example:

         char test[30];

         int a=2,b=3;

         int i=0;

         i=sprintf(test,"Add Test:a=%d,b=%d,a+b=%d",a,b,a+b);

         lr_output_message(test);

          //Add Test:a=2,b=3,a+b=5

         lr_output_message("i=%d",i);

          //i=22写入test的字符数量

    5.strlwrstrupr

      Strlwr把字符串全部变成小写,strupr把字符串全部变成大写。

      Char *strlwr(char *string); char *strupr(char *string);

      Example:

       char str[]="This is A tEst";

        lr_output_message("lowstr=%s",(char *)strlwr(str));

        //lowstr=this is a test

           lr_output_message("uprstr=%s",(char *)strupr(str));

        //uprstr=THIS IS A TEST

    6.atoiitoa

      Atoi是把一个字符串转为整数:int atoi(const char *string);

      string字符串转换成整数:i=atoi(“123fkdjas”);

      Itoa是把整数转化成字符串:int itoa(int value,char *string,int redix);

      把数字value转换成字符串放在string里,redix是转换时的进制。

      Itoa(131231,string,10);

    7.strlen

      用于返回指定字符串的字符个数。Size_t strlen(const char *string);

      len=strlen("This is a test");

    8.memcpy:

      用于在内存缓存区复制数据,可以复制二进制的数据,而前面的strcpy只能复制字符串,不能复制中间存在\0的数据。

      语法结构:

      void    memcpy(void *dest,const void *src,size_t n);

      dest是目标缓存区,src是将要复制的源缓存区,n是要复制的长度

      example:

       char src[]="AAAAA \0 This is test.\0";

       char memcpy_str[60];

       char strncpy_str[60];

     

       memcpy(memcpy_str,src,60);

       strncpy(strncpy_str,src,60);

     

       lr_output_message("memcpy_str=%s",memcpy_str);

       //memcpy_str=AAAAA 因为\0是字符串结束符,所以只输出了\0前面的字符

       lr_output_message("strncpy_str=%s",strncpy_str);

       //memcpy_str=AAAAA

       lr_output_message("memcpy_str:%s",memcpy_str+8);

       //memcpy_str:This is test.首位偏移8位后输出This is test

       lr_output_message("strncpy_str:%s",strncpy_str+8);

       //首位偏移后不输出任何东西

    9.memset

      函数通常用来对数据对象做初始化工作,void *memset(void *buffer,int c,size_t n);

     调用memset函数后,会把buffer指向的某一块内存中的每个字节的内容全部设置为参数c所指定的ASCII值或指定字符对应的ASCII值,块的大小由第三个参数n来指定。

    10.sizeof:

      用来返回指定表达式、变量或者指定数据类型在内存中所占用的字节数:

       sizeof(类型说明符、表达式或者数组) 或者sizeof 变量

       char test[10];

      struct str_test{

             char str[10];

             int i;

      };

      struct str_test mystr;

      lr_output_message("\"abcde\"size=%d",sizeof "abcde" ); //"abcde"size=6

      lr_output_message("12345 size=%d",sizeof(12345));//12345 size=4

      lr_output_message("test size=%d",sizeof test);//test size=10

      lr_output_message("mystr size=%d",sizeof(mystr));//mystr size=16

    2011-05-30

    1、文本文件与二进制文件:

       文本文件也称ASCII文件,其特点是每一个字符在键盘上存储时均对应一个字节,如12345存放时要5个字节;

       二进制文件特征:对于不同数据类型将按其实际占用的内存字节来存放,如12345存放要4个字节,因为它是整型数据。

    2、常用的Vuser文件操作函数:

       1.文件打开函数(fopen)FILE *fopen(const char *filename,const char *access_mode);

         Filename是要打开的文件路径;access_mode是打开模式。

         f=fopen(“d:\\temp.txt”,”r”);//以只读方式打开文件

       2.关闭文件函数(fclose): int fclose(FILE *file_pointer)

       3.读写文件函数:

         Size_t fread(void *buffer,size_t size,size_t count,FILE *file_pointer);

         Size_t fwrite(const void *buffer,size_t size,size_t count,FILE *file_pointer);

         Buffer是指向数据缓存区的指针,在fread中,buffer指向的数据缓存区用来保存读取的内容;在fwrite中,buffer指向数据的数据缓存区的数据将作为文件的输入数据来源。

         Sizebuffer指向缓存区数据类型在内存中占有的字节数,可以用sizeof函数来获取。

         Count是读或者写数据块的块数

         File_pointfopen返回的文件指针;

         Freadfwrite执行后将会返回实际读或者写的数据块块数,返回结果通常是指定的读写数据块数count;但是当有读写错误发生时,返回的实际读写块数将会小于count.

       4.文件定位函数(fseek)

         Int fseek(FILE *file_pointer,long offset,int origin)

         File_pointerfopen返回的文件指针;

         Offset是相对起始位置的偏移量;

         Origin是起始位置,共有3个取值:SEEK_SET(0)—文件的开始位置;SEEK_CUR(1)---文件指针的当前位置;SEEK_END(2)---文件的末尾。

          函数执行成功将会返回0,否则将会返回非零。

     

    2011-06-01

    1、字符串处理函数:

    Lr_save_string:用于把一个字符串保存到参数中;

      Int lr_save_string(const char *param_value,const char *param_name);

      Parm_value是将要进行保存的字符串;

      Parm_name是保存的参数名称;

      类似函数还有lr_save_intlr_save_datetime

    Lr_save_var:用来把字符串的一部分内存保存为参数;

      int       lr_save_var(const char *param_value,unsigned long const value_len,unsigned long options,const char *param_name);

      param_value是将要进行截取的字符串;

      value_len是将要截取的长度;

      options 是保留参数,可以设为0

      param_name是保存的参数名。

    Lr_eval_string:返回参数的实际内容;

      char     *lr_eval_string(const char *instring);

      instring是参数或者包含参数的字符串。

    Example:

        lr_save_string("abcdefghijklmn","ParamStr");

        lr_output_message("ParamStr=%s",lr_eval_string("{ParamStr}"));

           //ParamStr=abcdefghijklmn

           lr_save_var("1234567890",5,0,"ParamStr1");

           lr_output_message("ParamStr1=%s",lr_eval_string("{ParamStr1}"));

         //ParamStr1=12345

    2、消息处理函数:

       Lr_debug_message:向日志文件或者Controller控制台输出一个Debug类型消息;

       Lr_error_message:向日志文件或者Controller控制台发送一个Errors类型消息;

       Lr_log_message:向虚拟用户的日志文件发送消息;

       Lr_message:向日志文件或者Controller控制台发送普通类型消息;

       Lr_output_message:向日志文件或者Controller控制台发送一个通知类型消息;

       Lr_vuser_status_message:向Controller的虚拟用户状态窗口或者TuningModuleConsole的虚拟用户状态窗口发送一个消息,同时消息也会发送到日志文件中;

       Lr_set_debug_message:设置当前脚本的消息级别;

       Lr_get_debug_message:返回当前的消息设置级别。

    3、脚本信息函数:

       1.lr_whoamiVuserID、组名称、场景ID)传入参数的顺序必须这样的

       2.lr_get_vuser_ipVuGen运行脚本时返回为

  • LoadGenerator添加步骤

    2011-06-22 11:15:09

    LoadGenerators添加操作步骤:

    1、  配置装有LoadGenerator的机器上配置:代理配置:

    2、  编辑代理配置项:

    点击Settings进入配置窗口:

     3、配置MI Listener nameMI Listener User Name MI Listener Password

    其中:

    MI Listener name机器名或者机器IP地址

    MI Listener User Name:登录机器的用户名

    MI Listener Password:与上面User Name匹配的密码

     4、编辑好后要求重启LoadRunner Agent Process

    确定即可。

     5、在本机启动Controller,添加loadgenerators

          

    在弹出的Add New Load Generator窗口中输入Name loadgeneratorIP,选择操作系统

     6、点击LoadGenerators中的Connect按钮,当新添加的Load GeneratorStatusReady就说明连接成功:

       

     

    至此,Load Generator添加成功。

     

    注意:由于Load Generator运行时用户数是算做Controller的用户数的,所以如果你的License只有100的话,ControllerLoadGenerator加起来的用户数最多为100

  • LR使用webservice+http录制的时候提示的错误

    2010-03-02 18:28:57

    Exception in thread "main" java.lang.NoClassDefFoundError: com/stub/httpclient/H
    ttpClientStub
    Press any key to continue . . .

     

    vuser_init()
    {
        web_remove_auto_header("Content-Type", "ImplicitGen=Cond", LAST); //È¥³ýhttpÀïÃæµÄ¶àÓàÍ·
        web_add_auto_header("x-up-calling-line-id","{NewParam}");
     web_add_auto_header("User-Agent","Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/12.0.013; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML");
     web_add_auto_header("x-wap-profile","http://nds1.nds.nokia.com/uaprof/NN95_8GB-1r100.xml");
     web_add_auto_header("Host","176.18.30.82:18095");
     //web_add_auto_header("Content-Length","209");
        //web_add_auto_header("User-Agent","NokiaN80-1/3.0 (3.0617.0.5) Series60/3.0  Profile/MIDP-2.0 Configuration/CLDC-1.1");
     return 0;
    }

    Action()
    {
        web_reg_find("Text=000000",
      LAST);
     web_custom_request("login",
            "Method=POST",
            "URL=http://176.18.30.82:18095/service/login.do",
            "Body=<InterWBSC><Ver>111</Ver><Client>100202</Client><Se"
            "ssion></Session><TransId>{traid}</TransId><TestFlag>0</TestFlag><UVer>1.0</UVer"
            "><Lang>en</Lang><Body></Body></InterWBSC>",
           LAST);
     
      
     return 0;
    }

     

     

    POST /service/login.do HTTP/1.1
    HOST: 176.18.30.82:18095
    Content-Length:166
    x-up-calling-line-id:15999999999
    User-Agent:nokia8250
    x-wap-profile:http://nds1.nds.nokia.com/uaprof/NN95_8GB-1r100.xml
    --------------------------------------------------
    <InterWBSC><Ver>1.0</Ver><Client>100202</Client><Session></Session><TransId>1000</TransId>
    <TestFlag>0</TestFlag><UVer>0.1</UVer><Lang>en</Lang><PFlag>0</PFlag><Body></Body>
    </InterWBSC>

     

     

    设置:classpath试一试吧:

    把classpath设成C:\Program Files\Java\jre1.5.0_06\lib 这种设法下,java会查找这个目录下的.class文件,但是,不会去用这个目录下的.jar文件.所以必须把所有用到的.class文件都放在这个文件夹里

  • 我有一个好都想法

    2009-01-02 16:01:18

    如果现在51testing建一个不分班的大QQ群就好了,那样的话更热闹。
Open Toolbar