2013-10-08 13 views
5

私は、WebベースのHR/SWシステムをテストするためにSelenium IDEを使用しています。Selenium IDEでデータプールから変数を読み取るにはどうすればよいですか?

従業員の休暇を入力するための画面があります。

私は約3000人の従業員を雇っています。

変数を使用して1人の従業員に休暇を入力するテストケースを作成しました。

3000ケースのテストケースを作成せずに3000人の従業員すべてに対してテストケースを繰り返すにはどうすればよいですか。そうすることは不可能な努力を要するだろう。注:各従業員は異なる休暇データ(タイプ、開始日、終了日)を持っています

変数がデータを読み取るために使用できるファイル(Excelなど)を使用する方法はありますか?

私の場合の解決策はありますか?

私は非常に非常に私が誰かが私を助けることができて感謝します。

ありがとうございます。

+0

あなたがIDEのできることの終わりに達しているように思えます。 – Arran

+0

NO!お願いします!!どんな仕事? – 2ousy

答えて

0

あなたが使用する必要があると思いますloopあなたのコードが表示されないので、this oneselenium-ide loopにチェックしてください。評判が十分ではないので、あなたの質問にはコメントできません。可能であれば、あなたのコードをあなたの質問に加えてください。

+0

ありがとうございました。非常に役に立ちました – 2ousy

5

XMLファイルを入力として使用できます。 - (http://51elliot.blogspot.com/2008/02/selenium-ide-goto.html - さらに、この記事では、ユーザーの拡張ファイルを追加する方法を説明します)

datadriven.js

sideflow.js

1)は、最初に次のようなユーザーの拡張機能を追加する必要があります

include.js

現時点で私は最後の2つを取ったリンクを見つけることができませんので、私は自分の投稿の最後にコードを与えます。コードは私の作業ディレクトリから取得します。あなたは、コードをコレスポンデントファイルに置き、SelemiunIDEユーザー拡張にファイルを追加して使用するだけです。

2)は、XMLファイルtest_data.xmlを作成します。

$ {データパス} - ディレクトリへのフルパス:このようなテストケースの使用コードで

<testdata> 
    <test employee="1" type="1" startDate="01.01.2013" endDate="01.02.2013" /> 
    <test employee="2" type="1" startDate="01.02.2013" endDate="01.03.2013" /> 
    <test employee="3" type="1" startDate="01.03.2013" endDate="01.04.2013" /> 
... 
</testdata> 

3):XML-ファイル

<!--BEGIN LOOP--> 
<tr> 
    <td>loadTestData</td> 
    <td>file://${DataDir}/test_data.xml</td> 
    <td></td> 
</tr> 
<tr> 
    <td>while</td> 
    <td>!testdata.EOF()</td> 
    <td></td> 
</tr> 
<tr> 
    <td>nextTestData</td> 
    <td></td> 
    <td></td> 
</tr> 
<tr> 
    <td>echo</td> 
    <td>employee=${employee} type=${type} ...</td> 
    <td></td> 
</tr> 
... 
<!--END LOOP--> 
<tr> 
    <td>endWhile</td> 
    <td></td> 
    <td></td> 
</tr> 

使用されているユーザーの拡張子を持ちます

が含まれます。JS

/** 
* Original Developer: Jerry Qian([email protected]) 
* Modified By: John Witchel ([email protected]) 
* include extension for Selenium-IDE edition 
* refer to includeCommand_2.1.3 for Selenium-Core edition 
* @version 1.3 
* 
*/ 
function IDEIncludeCommand() {} 

IDEIncludeCommand.LOG_PREFIX = "IDEIncludeCommand: "; 
IDEIncludeCommand.BEGIN_TEMPLATE = "begin$Template$"; 
IDEIncludeCommand.END_TEMPLATE = "end$Template$"; 
IDEIncludeCommand.VERSION = "1.1"; 

IDEIncludeCommand.prototype.prepareTestCaseAsText = function(responseAsText, paramsArray) { 
    /** 
    * Prepare the HTML to be included in as text into the current testcase-HTML 
    * Strip all but the testrows (tr) 
    * Stripped will be: 
    * - whitespace (also new lines and tabs, so be careful wirt parameters relying on this), 
    * - comments (xml comments)     
    * Replace variable according to include-parameters 
    * note: the include-variables are replaced literally. selenium does it at execution time 
    * also note: all selenium-variables are available to the included commands, so mostly no include-parameters are necessary 
    * 
    * @param responseAsText table to be included as text (string) 
    * @return testRows array of tr elements (as string!) containing the commands to be included 
    * 
    * TODO: 
    * - selenium already can handle testcase-html. use selenium methods or functions instead 
    * - find better name for requester 
    */ 
    // removing new lines, carret return and tabs from response in order to work with regexp 
    var pageText = responseAsText.replace(/\r|\n|\t/g,""); 
    // remove comments 
    // begin comment, not a dash or if it's a dash it may not be followed by -> repeated, end comment 
    pageText = pageText.replace(/<!--(?:[^-]|-(?!->))*-->/g,""); 
    // find the content of the test table = <[spaces]table[char but not >]>....< /[spaces]table[chars but not >]> 
    var testText = pageText.match(/<\s*table[^>]*>(.*)<\/\s*table[^>]*>/i)[1]; 

    // Replace <td></td> with <td>&nbsp;</td> for iE - credits Chris Astall 
    // rz: somehow in my IE 7 this is not needed but is not bad as well 
    testText = testText.replace(/<\s*td[^>]*>\s*<\s*\/td[^>]*>/ig,"<td></td>");// jq: no space 

    // replace vars with their values in testText 
    for (var k = 0 ; k < paramsArray.length ; k++) { 
     var pair = paramsArray[k]; 
     testText = testText.replace(pair[0],pair[1]); 
    } 

    // removes all < /tr> 
    // in order to split on < tr> 
    testText = testText.replace(/<\/\s*tr[^>]*>/ig,""); 
    // split on <tr> 
    var testRows = testText.split(/<\s*tr[^>]*>/i); 
    return testRows; 
}; 

IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest = function(includeUrl) { 
    /** 
    * Prepare and do the XMLHttp Request synchronous as selenium should not continue execution meanwhile 
    * 
    * note: the XMLHttp requester is returned (instead of e.g. its text) to let the caller decide to use xml or text 
    * 
    * selenium-dependency: uses extended String from htmlutils 
    * 
    * TODO use Ajax from prototype like this: 
    * var sjaxRequest = new Ajax.Request(url, {asynchronous:false}); 
    * there is discussion about getting rid of prototype.js in developer forum. 
    * the ajax impl in xmlutils.js is not active by default in 0.8.2 
    * 
    * @param includeUrl URI to the include-document (document has to be from the same domain) 
    * @return XMLHttp requester after receiving the response 
    */ 
    var url = this.prepareUrl(includeUrl); 
    // the xml http requester to fetch the page to include 
    var requester = this.newXMLHttpRequest(); 
    if (!requester) { 
     throw new Error("XMLHttp requester object not initialized"); 
    } 
    requester.open("GET", url, false); // synchron mode ! (we don't want selenium to go ahead) 
    try { 
     requester.send(null); 
    } catch(e) { 
     throw new Error("Error while fetching url '" + url + "' details: " + e); 
    } 
    if (requester.status != 200 && requester.status !== 0) { 
     throw new Error("Error while fetching " + url + " server response has status = " + requester.status + ", " + requester.statusText); 
    } 
    return requester; 
}; 

IDEIncludeCommand.prototype.prepareUrl = function(includeUrl) { 
    /** Construct absolute URL to get include document 
    * using selenium-core handling of urls (see absolutify in htmlutils.js) 
    */ 
    var prepareUrl; 
    // htmlSuite mode of SRC? TODO is there a better way to decide whether in SRC mode? 
    if (window.location.href.indexOf("selenium-server") >= 0) { 
     LOG.debug(IDEIncludeCommand.LOG_PREFIX + "we seem to run in SRC, do we?"); 
     preparedUrl = absolutify(includeUrl, htmlTestRunner.controlPanel.getTestSuiteName()); 
    } else { 
     preparedUrl = absolutify(includeUrl, selenium.browserbot.baseUrl); 
    } 
    LOG.debug(IDEIncludeCommand.LOG_PREFIX + "using url to get include '" + preparedUrl + "'"); 
    return preparedUrl; 
}; 

IDEIncludeCommand.prototype.newXMLHttpRequest = function() { 
    // TODO should be replaced by impl. in prototype.js or xmlextras.js 
    //  but: there is discussion of getting rid of prototype.js 
    //  and: currently xmlextras.js is not activated in testrunner of 0.8.2 release 
    var requester = 0; 
    var exception = ''; 
    // see http://developer.apple.com/internet/webcontent/xmlhttpreq.html 
    // changed order of native and activeX to get it working with native 
    // xmlhttp in IE 7. credits dhwang 
    try { 
     // for IE/ActiveX 
     if(window.ActiveXObject) { 
      try { 
       requester = new ActiveXObject("Msxml2.XMLHTTP"); 
      } 
      catch(e) { 
       requester = new ActiveXObject("Microsoft.XMLHTTP"); 
      } 
     } 
     // Native XMLHttp 
     else if(window.XMLHttpRequest) { 
      requester = new XMLHttpRequest(); 
     } 
    } 
    catch(e) { 
     throw new Error("Your browser has to support XMLHttpRequest in order to use include \n" + e); 
    } 
    return requester; 
}; 

IDEIncludeCommand.prototype.splitParamStrIntoVariables = function(paramString) { 
    /** 
    * Split include Parameters-String into an 2-dim array containing Variable-Name and -Value 
    * 
    * selenium-dependency: uses extended String from htmlutils 
    * 
    * TODO: write jsunit tests - this could be easy (if there were not the new RegExp) 
    * 
    * @param includeParameters string the parameters from include call 
    * @return new 2-dim Array containing regExpName (to find a matching variablename) and value to be substituted for 
    */ 
    var newParamsArray = new Array(); 
    // paramString shall contains a list of var_name=value 
    var paramListPattern = /([^=,]+=[^=,]*,)*([^=,]+=[^=,]*)/; 
    if (! paramString || paramString === "") { 
     return newParamsArray; 
    } else if (paramString.match(paramListPattern)) { 
     // parse parameters to fill newParamsArray 
     var pairs = paramString.split(","); 
     for (var i = 0 ; i < pairs.length ; i++) { 
      var pair = pairs[i]; 
      var nameValue = pair.split("="); 
      //rz: use String.trim from htmlutils.js of selenium to get rid of whitespace in variable-name(s) 
      var trimmedNameValue = new String(nameValue[0]).trim(); 
      // the pattern to substitute is ${var_name} 
      var regExpName = new RegExp("\\$\\{" + trimmedNameValue + "\\}", "g"); 

      if (nameValue.length < 3) { 
       newParamsArray.push(new Array(regExpName,nameValue[1])); 
      } else { 
       var varValue = new String(nameValue[1]); 
       for (var j = 2; j < nameValue.length; j++) { 
        varValue=varValue.concat("="+nameValue[j]); 
       } 
       newParamsArray.push(new Array(regExpName,varValue)); 
      } 
     } 
    } else { 
     throw new Error("Bad format for parameters list : '" + paramString + "'"); 
    } 
    return newParamsArray; 
}; 

IDEIncludeCommand.prototype.doInclude = function(locator, paramString) { 
    // Rewrite logic for Selenium IDE by Jerry Qian 
    var currentSelHtmlTestcase = testCase; 

    var includeCmdRow = testCase.debugContext.currentCommand(); 

    if (!includeCmdRow) { 
     throw new Error("IDEIncludeCommand: failed to find include-row in source testtable"); 
    } 

    var paramsArray = this.splitParamStrIntoVariables(paramString); 

    var inclDoc = this.getIncludeDocumentBySynchronRequest(locator); 

    // Get an array of commands from the include text with all whitespace stripped 
    var includedTestCaseHtml = this.prepareTestCaseAsText(inclDoc.responseText, paramsArray); 


    this.injectIncludeTestCommands(locator,includeCmdRow,includedTestCaseHtml); 
}; 

IDEIncludeCommand.prototype.injectIncludeTestCommands = function(locator,includeCmdRow, testRows) { 
    // Rewrite logic for Selenium IDE by Jerry Qian 
    var newCommands = new Array(); 
    // skip first element as it is empty or <tbody> 
    for (var i = 1 ; i < testRows.length; i++) { 
      if(i == 1){// add BEGIN-END block 
      var beginCommand = new Command(IDEIncludeCommand.BEGIN_TEMPLATE,locator,"");  
      newCommands.push(beginCommand); 
      } 

      var newText = testRows[i]; 
      if(newText.match(/<\s*td.*colspan=.*>(.*)<\/\s*td[^>]*>/i)){//delete comment step 
      continue; 
      } 

      // removes all < /td> 
      // in order to split on <td> 
      newText = newText.replace(/<\/\s*td[^>]*>\s*<\/\s*tbody[^>]*>/ig,""); //remove </tbody>first 
      newText = newText.replace(/<\/\s*td[^>]*>/ig,""); 
      var newCols = newText.split(/<\s*td[^>]*>/i); 
      var new_cmd,new_target,new_value; 

      for (var j = 1 ; j < newCols.length; j++) {//skip 0 
      if(j == 1) { 
       new_cmd = newCols[j].replace(/\s/g,"");//trim \s 
      }else if(j == 2) { 
       new_target = newCols[j].replace(/\s+$/g,"");//trim end \s 
      }else if(j == 3) { 
       new_value = newCols[j].replace(/\s+$/g,"");//trim end \s 
      } 
      } 

      var newCommand = new Command(new_cmd,new_target,new_value); 
      newCommands.push(newCommand); //correct all steps 
    } 
    var endCommand = new Command(IDEIncludeCommand.END_TEMPLATE,locator,"");  
    newCommands.push(endCommand);//add BEGIN-END block 


    var cmsBefore = testCase.commands.slice(0,testCase.debugContext.debugIndex + 1);  
    var cmdsBehind = testCase.commands.slice(testCase.debugContext.debugIndex + 1, testCase.commands.length);  
    testCase.commands = cmsBefore.concat(newCommands).concat(cmdsBehind);//Injection 

    // Don't inject if it appears the injection has already been done 
    // (i.e., if the next command is the BEGIN). 
    if (testCase.commands.length <= testCase.debugContext.debugIndex+1 
     || beginCommand.toString() != testCase.commands[testCase.debugContext.debugIndex+1].toString()) 
    { 
     // The include command cannot be the last command in the TestCase, or else 
     // the de-injection code in doEnd$Template$ will cause an error. So we'll 
     // add a simple echo if it is the last. 
     if (testCase.commands.length == testCase.debugContext.debugIndex+1) 
     { 
      // Using concat instead of push so that we don't trigger the TestCase's set-modified flag. 
      testCase.commands = testCase.commands.concat(new Command("echo", "The include command cannot be the last line in a TestCase, so this command was added. It can be left in place or removed, as desired.", "The include command cannot be the last line in a TestCase, so this command was added. It can be left in place or removed, as desired.")); 
     } 

     // This is original code. 
     var cmsBefore = testCase.commands.slice(0,testCase.debugContext.debugIndex + 1); 
     var cmdsBehind = testCase.commands.slice(testCase.debugContext.debugIndex + 1, testCase.commands.length); 
     testCase.commands = cmsBefore.concat(newCommands).concat(cmdsBehind);//Injection 
    } 
}; 

Selenium.prototype.doInclude = function(locator, paramString) { 
    LOG.debug(IDEIncludeCommand.LOG_PREFIX + "Version " + IDEIncludeCommand.VERSION); 
    var ideIncludeCommand = new IDEIncludeCommand(); 
    ideIncludeCommand.doInclude(locator, paramString); 

    // If goto scripts exist then reindex the labels. goto_sel_ide.js creates an array of labels when the 
    // script is initialized but an included file's labels are not part of that initial read, so this function 
    // re-initializes that array with the included files labels (if any). If goto_sel.ide.js is not included 
    // it's ignored. 
    try { 
     this.initialiseLabels(); 
    } 
    catch (e) { 
     LOG.debug("Goto Script not used."); 
    } 

}; 

// Array to hold the starting position of the Begin$Template$ marker. Pushing and popping the position onto an array 
// allows us to correctly handle nested includes during clean up. 
var beginTemplateIndex = new Array(); 

// Mark the beginning of the include 
Selenium.prototype.doBegin$Template$ = function(locator){ 
    LOG.info("Begin Template " + locator + " at position " + testCase.debugContext.debugIndex); 
    // Add the current position to the tail of the beginTemplateIndex 
    beginTemplateIndex.push(testCase.debugContext.debugIndex); 
}; 

// Clean up everything between the closest Begin$Template$ and this $End$Template$, and pop the position off the array. 
Selenium.prototype.doEnd$Template$ = function(locator){ 

    // Remove the last Begin$Template$ from the tail of the beginTemplateIndex 
    var currentBeginTemplateIndex = beginTemplateIndex.pop(); 
    LOG.info("End Template " + locator + " at position " + currentBeginTemplateIndex); 

    // Delete the commands that we injected in injectIncludeTestCommands. 
    testCase.commands = 
     testCase.commands.slice(0,currentBeginTemplateIndex).concat(
      testCase.commands.slice(testCase.debugContext.debugIndex+1, testCase.commands.length)); 

    // Set the current command to the next one after the injected block. 
    testCase.debugContext.debugIndex = currentBeginTemplateIndex-1; 

    //Must refresh to syncup UI 
    editor.view.refresh(); 
}; 

datadriven.js

/************************************ DATADRIVEN EXTENSION START ********************************************/ 
/* 
NAME: 
    datadriven 

    Licensed under Apache License v2 
    http://www.apache.org/licenses/LICENSE-2.0 

PURPOSE: 
    Basic data driven testing. 

    Full documentation at http://wiki.openqa.org/display/SEL/datadriven 


EXAMPLE USE: 
    The structure of your data driven test case will be; 
    ------------------------------------------- 
    COMMAND  |TARGET   |VALUE 
    ------------------------------------------- 
    loadTestData |<file path>  | 
    while   |!testdata.EOF() | 
    testcommand1 |    | 
    testcommand...|    | 
    testcommandn |    | 
    endWhile  |    | 
    ------------------------------------------- 

AUTHOR: 
    Jonathan McBrien 
    [email protected] 
    2008-10-22: v0.1: Initial version. 
    2009-01-16: v0.2: Updated for Firefox 3. 
       xmlTestData.prototype.load now uses the include extension's getIncludeDocumentBySynchronRequest method for better portability. 
       (Why reinvent the wheel? :) - with appreciation to the include extension's authors.) 
*/ 

XML.serialize = function(node) { 
    if (typeof XMLSerializer != "undefined") 
     return (new XMLSerializer()).serializeToString(node) ; 
    else if (node.xml) return node.xml; 
    else throw "XML.serialize is not supported or can't serialize " + node; 
} 

function xmlTestData() { 
    this.xmlDoc = null; 
    this.testdata = null; 
    this.index = null; 
} 


xmlTestData.prototype.load = function(xmlloc) { 
    loader = new IDEIncludeCommand(); 
    var xmlHttpReq = loader.getIncludeDocumentBySynchronRequest(xmlloc); 
    this.xmlDoc = xmlHttpReq.responseXML; 

    this.index = 0; 
    this.testdata = this.xmlDoc.getElementsByTagName("test"); 

    if (this.testdata == null || this.testdata.length == 0) { 
     throw new Error("Test data couldn't be loaded or test data was empty."); 
    } 
} 

xmlTestData.prototype.EOF = function() { 
    if (this.index != null && this.index < this.testdata.length) return false; 
    return true; 
} 

xmlTestData.prototype.more = function() { 
    return !this.EOF(); 
} 

xmlTestData.prototype.next = function() { 
    if (this.EOF()) { 
     LOG.error("No test data."); 
     return; 
    } 

    LOG.info(XML.serialize(this.testdata[this.index])); // Log should anything go wrong while testing with this data. 

    if (this.testdata[this.index].attributes.length != this.testdata[0].attributes.length) { 
     LOG.error("Inconsistent attribute length in test data."); 
     return; 
    } 

    for (i=0; i<this.testdata[this.index].attributes.length; i++){ 
     if (null == this.testdata[0].getAttribute(this.testdata[this.index].attributes[i].nodeName)) { 
      LOG.error("Inconsistent attribute names in test data."); 
      return; 
     } 

     selenium.doStore(this.testdata[this.index].attributes[i].nodeValue, this.testdata[this.index].attributes[i].nodeName); 
    } 

    this.index++; 
} 

Selenium.prototype.testdata = null; 

Selenium.prototype.doLoadTestData = function(xmlloc) { 
    testdata = new xmlTestData(); 
    testdata.load(xmlloc); 
}; 

Selenium.prototype.doNextTestData = function() { 
    testdata.next(); 
}; 

/************************************ DATADRIVEN EXTENSION END **********************************************/ 
+0

実際に現在のSelBlocksにはこのすべてが含まれています.. – Dee

1

また、この非常に素晴らしいブログの記事をチェックすることができます。 http://seleniumworks.blogspot.com/2014/01/selenium-ide-data-driven.html

これは、必要なプラグインを使用する方法について説明します、どこでそれらをダウンロードする。それは私のために完璧に働いた。

この回答は、上記の記事を見つけるために私が彼の答えを使用したので、@ Yevgen Ulyanenkovによって提供されたアプローチとほとんど同じアプローチをしています。しかし、もっとうまくグーグルがいて、それがうまくいけば誰かに役立つだろう。

2

現在のソリューションは、あなたがXMLでデータセットに応じてサイクルを行うことができますSelBlocksコンポーネントです

ForXML | XMLFileName.XML 
... test case steps 
EndForXML 

XMLが利用できるように

<testdata> 
    <vars storedVariable1="xxxxx" storedVariable2="yyyyy" .. storedVariableN="zzzzz" /> 
    .. other record(s) 
</testdata> 

各格納された変数のVILL特定の構造を持っている必要がありますテストケースでは${storedVariableN}となります。

あなたはこのような式を使用してMS ExcelやLibreOfficeのことでXMLを生成し、テーブル全体にコピーすることができます

="<vars "& 
" "&$A$1&"="""&A2&""" "& 
" "&$B$1&"="""&B2&""" "& 
.. 
" "&$X$1&"="""&X2&""" "& 
"/>") 

XMLは、簡単にデータセットの各変更後copypastedすることができます。

セルブロックには、以前の回答で述べたwhile、datadriven、goto、loopなどの拡張が含まれています。あなたはここに完全なリファレンスを参照してくださいSelblocksなど条件ジャンプ、条件、キャッチしようとしたブロック、関数などの他の機能を使用することができます。http://refactoror.wikia.com/wiki/Selblocks_Reference

、新しいセレン3リリースと、それは保証されませんSelのコア不在でを用心しますSelblockアドオンのテストは、Firefoxの将来のバージョンで動作します。

関連する問題