Selenium检查日志文件

时间:2015-05-05 12:11:00

标签: java testing selenium selenium-webdriver

有没有人知道是否可以使用selenium WebDriver(我使用java)检查日志文件中的消息?

目前,了解我们系统前端的操作是否已完成的唯一方法是ssh到我们的服务器并等待日志文件的确认。这是手动测试过程的方法,但现在我需要自动化测试。是否可以使用硒来检查这个?

我目前实现这一目标的方法似乎过于复杂:

  • 在前端运行操作
  • 启动shell脚本以检查Selenium Test中的日志文件(包括ssh到服务器,因为日志存储在那里)
  • 在服务器上的简单文本文件中创建“操作已完成”消息,如果日志显示操作已完成,否则显示“操作未完成”
  • scp文件返回我的机器/ VM
  • 在文件中读到eclipse
  • 在测试中创建方法以检查文件的内容,例如if(“Action completed”消息被返回 - >继续)else(从子弹点2重复)

有更简单的方法???

5 个答案:

答案 0 :(得分:1)

自我答案 - 在考虑了所有帖子之后,这是我提出的解决方案非常有效。我有一个允许我使用Eclipse中的正则表达解析日志的方法。以下是重点评论的代码,以显示我所做的......

public void checkLogs() throws IOException{
    //create an empty string to hold the output 
    String s = null;

    // using the process API and runtime exec method to directly ssh in the client machine and run any command you like. I need the live logs so I used tail -f
    Process p = Runtime.getRuntime().exec("ssh user@ipaddress tail -f /location/file");
    // use buffered reader to bring the output of the command run on the clinet machine back to the output in eclipse. I also created an output for the error stream to help with debugging if the commands dont work as I am not directly looking at the output when I run the commands on the client machine
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

    BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

    // For my test I only want to continue with the clicks in the front end once I know the system has been reset. For our system this can only be checked in the logs. So I created a boolean flag  which will only become true once the regex I run matches lines from the output. Use a while loop with != null to check every line of the output
    boolean requestArrived = false;
    while ((s = stdInput.readLine()) != null) {
        System.out.println(s); // so I can see live what is happening. (great for debugging)
        //search for the specific string that lets me know the system has been started the reset. (can run any regex here)
        if(r.equalsIgnoreCase("system reset request received")){
            System.out.println("***********************************************************************************************");
            // Change the state of the boolean flag to true as we know now that the backend is ready to continue
            requestArrived = true;
        }

        if(t.equalsIgnoreCase("System reset has happened successfully"))// a secondary check to see when the system is ready to continue{
            System.out.println("##############################################################################################");
            //if both string that we are looking for have been received we can continue with the rest of the script
            if (requestArrived) {
                break;
            }
        }
    }
    //close the terminal 
    p.destroy();

}

我希望能帮助某人:)

答案 1 :(得分:0)

向您的站点添加一个特殊页面,用于记录日志文件。如果您需要保持日志文件的机密性,请拥有selenium知道的共享密钥和站点。然后只需访问该页面并使用常用方法检查字符串

可能需要克服一些权限问题:通常,Web应用程序无法查看日志。

答案 2 :(得分:0)

根据您描述的现有解决方案,Selenium不是真正适合该工作的工具(即使您可能找到解决方案)。

我可以看到几种可能的方法:

  1. 添加一个显示进度的页面(由Vorsprung建议)。这可以是单独的页面,也可以是现有GUI中的某些消息。这可能仅适用于Selenium,或者它甚至可能成为所有用户(或仅适用于管理员)的适当功能,如果它对您的系统有意义的话。
  2. 使用您描述的系统,但在本地系统上运行服务器(作为特殊的测试实例)。然后你可以跳过SSHing。
  3. 在服务器上创建一些服务(REST或类似服务)以查询作业状态。同样,这可能不仅仅是测试。
  4. 有意义取决于系统的使用方式(用户当前如何检查作业是否已完成,有关作业的信息是否有趣等)。

答案 3 :(得分:0)

编辑:我误解了你的问题,因为你要求的是一个更简单的解决方案,但我试图为复杂的方法提供解决方案。无论如何,我希望它会有用。

实际答案:

我为我的项目完成了以下活动

  1. 使用远程unix服务器上的shell脚本清除日志
  2. 执行前端活动
  3. 在预定义时间(例如,60秒)后捕获日志
  4. SFtp返回客户端计算机
  5. 首先,您需要一个SFTP客户端和SSH客户端来与unix服务器进行交互 这里Node是一个包含Unix env细节的对象。所以要相应改变。 使用 JSch lib进行此操作

    public static String runCommand(String Command, Node node )
    {
        String output = null;
        if (node.getConnType().equals("SSH")){
            int exitStatus = 0;
            try{
                  JSch jsch=new JSch();  
    
                  JSch.setConfig("StrictHostKeyChecking", "no"); 
    
                  Session session=jsch.getSession(node.getUserName(), node.getHost(), 22);
    
                  session.setPassword(node.getPassword());
                  session.setConfig("PreferredAuthentications",
                             "publickey,keyboard-interactive,password");
    
                  session.connect();
    
                  String command=Command;
    
                  Channel channel=session.openChannel("exec");
                  ((ChannelExec)channel).setCommand(command);
    
                  channel.setInputStream(null);
                  ((ChannelExec)channel).setErrStream(System.err);
                  InputStream in=channel.getInputStream();
                  channel.connect();
    
                  byte[] tmp=new byte[1024];
                  while(true){
                    while(in.available()>0){
                      int i=in.read(tmp, 0, 1024);
                      if(i<0)break;
                      output = new String(tmp, 0, i);
                    }
                    if(channel.isClosed()){
                      if(in.available()>0) continue; 
                      exitStatus= channel.getExitStatus();
                      //System.out.println("exit-status: "+exitStatus);
                      break;
                    }
                    try{Thread.sleep(1000);}catch(Exception ee){}
                  }
                  channel.disconnect();
                  session.disconnect();
                }
                catch(Exception e){
                  e.printStackTrace();
                }
               if (exitStatus == 0)
               {
                   if(output != null)
                       return output.replaceAll("[\\n\\r]", "");
               }
        }
        return null;
      }
    

    SFTP客户端

    public boolean transferFileSFTP(Node node,String srcDir,String targetDir,String srcFileName,String targetFileName, String direction)
     {
        JSch jsch = new JSch();
        Session session = null;
        try {
            session = jsch.getSession(node.getUserName(), node.getHost(), 22);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setConfig("PreferredAuthentications", 
                    "publickey,keyboard-interactive,password");
            session.setPassword(node.getPassword());
            session.connect();
    
            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;
            System.out.println("src:" + srcDir+srcFileName );
            System.out.println("target:" + targetDir+targetFileName );
            sftpChannel.get(targetDir+targetFileName, srcDir+srcFileName);
            sftpChannel.exit();
            session.disconnect();
            return true;
        } catch (JSchException e) {
            e.printStackTrace(); 
        } catch (SftpException e) {
            e.printStackTrace();
        }
        return false;
    }
    

    现在, 等到所需的时间并使其基于线程以同时从涉及的不同应用程序收集日志, 使用 ExecutorService Future&lt; String&gt; 实用程序

    因此创建了一个将启动请求的LogCollector类,另一个是将在日志文件上执行活动的ThreadClass(逻辑)。

    <强> LogCollector.java

    public class LogCollector {
    
        private static ExecutorService pool = Executors.newFixedThreadPool(100);
        private static List<Future<String>> list = new ArrayList<Future<String>>();    
    
        public static void add(Node node, String srcDir, String targetDir, String srcFileName, String targetFileName, long wait )
        {
            list.add(pool.submit(new LogCollectorThread(System.currentTimeMillis()/1000,wait, srcDir,  targetDir,  srcFileName,  targetFileName, node )));                      
        }
    
        public static void getResult()
        {   
            try{
                for (Future<String> future : list) {
                    String out =future.get();
                    //DO whatever you want to do with a response string return from your thread class
                }
                pool.shutdown();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }     
        } 
    
    } 
    

    <强> LogCollectorThread.java

    public class LogCollectorThread implements Callable<String>{
        long startTime;
        long wait;
        String srcFileName;
        String targetFileName;
        String srcDir;
        String targetDir;
        Node node;
    
        public LogCollectorThread(long startTime, long wait,String srcDir, String targetDir,String srcFileName, String targetFileName, 
                 Node node) {
            super();
            this.startTime = startTime;
            this.wait = wait;
            this.srcFileName = srcFileName;
            this.targetFileName = targetFileName;
            this.srcDir = srcDir;
            this.targetDir = targetDir;
            this.node = node;
        }
        /***
         * Returns a String with Parameters separated by ',' and status at the end 
         * status values:
         *   0 - successfully retrieved log file
         *   1 - failure while retrieving log file
         */
        @Override
        public String call() throws Exception {
            while((System.currentTimeMillis()/1000 - startTime)<=wait)
            {
                Thread.sleep(1000);
            }
            MyFTPClient sftp= new MyFTPClient();
            boolean result =sftp.transferFileSFTP(this.node, this.srcDir, this.targetDir, this.srcFileName, this.targetFileName, "From");
            System.out.println(this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName);
            if(result == true)
                return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "0" ;
            else
                return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "1" ;
         }
    }
    

    如何使用LogCollector类:

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
        Helper.runCommand("cd /opt/redknee/app/crm/current/log/; echo > AppCrm.log", testEnv.getBSS());
    
        LogCollector.add(testEnv.getBSS(), "collectedLogs\\", "/opt/redknee/app/crm/current/log/", timeStamp + "_" + testEnv.getBSS().getHost() + "_BSS_AppCrm.log"  , "AppCrm.log", 60);
    
        //So your thread is working now, so now perform your Front End Activity
        //After 60 seconds, log file will be SFTPed to client host
        //You can perform you activity before adding logCollectorThread or just before that
    
        LogCollector.getResult();
    

    这里我给了太多代码, 但是逐行描述每个步骤太难了。 我想证明的主要事情是使用java,大多数事情都是可能的。 你应该决定它的重要程度和价值。

    现在满足您搜索特定字符串的确切要求。

    正如你在logCollectorThread中看到的那样, 目前我什么都不做,只是等到60秒才能完成。 所以在这里你可以使用runCommand从日志中grep所需的字符串 你可以使用像

    这样的命令
     grep -i  "Action Completed" | grep -v 'grep' | wc -l
    

    如果它返回1,你找到了你的字符串 同样,您可以检查失败消息。 并从您的线程返回所需的字符串,并在threadCollector.getResult()方法中得到它。

    一旦文件被FTP到您的客户端,使用Java解析它的特定字符串将非常容易。 StackOverflow将帮助您:)

    declaimer:不要指望代码完全正常工作。 它会起作用,但你必须付出努力。插入缺失的部分需要你的java知识

答案 4 :(得分:-1)

要检查已完成的操作,检查服务器日志可能是解决方案。但仍然在GUI中,我们可以看到一些html元素或消息或java脚本变量或覆盖javscript函数的可见性。

Selenium JavscriptExecutor的帮助下,我们可以覆盖alert method(参见示例21),同样我们可以覆盖onreadystatechange以完成请求/响应。

JavaScript窗口变量可用于通过选中after each ajax request来显示操作完整性。

我们可以使用selenium等待元素可见,识别元素using xpath

以下链接中提供了更多教程,用于元素等待,在文本框中键入等等。 http://software-testing-tutorials-automation.blogspot.com/2014/05/selenium-webdriver-tutorials-part-two.html