2014-07-24 2 views
5

이 새로운 내보내기 기능이이 응용 프로그램에서 개발되었으며 Behat/Mink를 사용하여 테스트하려고합니다. 여기서 문제는 내보내기 링크를 클릭하면 페이지의 데이터가 CSV로 내보내지고/Downloads 아래에 저장되지만 페이지에 응답 코드 또는 기타 내용이 표시되지 않습니다.Behat에서 파일 다운로드를 테스트하는 방법

CSV를 내보내고/Downloads 폴더로 이동하여 파일을 확인할 수있는 방법이 있습니까?

+1

downvote에 대한 정당성은 무엇입니까 ?? 그건 절대 농담이 아니야 .. 진짜로 .. –

답변

2

Selenium 드라이버를 사용한다고 가정하고 다운로드가 완료 될 때까지 $this->getSession()->wait(30) 링크를 "클릭"하고 다운로드 폴더를 확인하십시오.

가장 간단한 해결책이 될 것입니다. 또는 BrowserMob과 같은 프록시를 사용하여 모든 요청을보고 응답 코드를 확인할 수 있습니다. 그러나 그것은 그 혼자만을위한 정말로 고통스러운 길 일 것입니다.

파일이 다운로드되었는지 확인하는 가장 간단한 방법은 기본 어설 션으로 다른 단계를 정의하는 것입니다. 같은 이름의 파일을 다운로드하고 브라우저가 다른 이름으로 저장할 때

/** 
* @Then /^the file ".+" should be downloaded$/ 
*/ 
public function assertFileDownloaded($filename) 
{ 
    if (!file_exists('/download/dir/' . $filename)) { 
     throw new Exception(); 
    } 
} 

이 상황에서 문제가 될 수 있습니다. 해결책으로 @BeforeScenario 후크를 추가하여 알고있는 파일 목록을 지울 수 있습니다.

다른 문제는 다운로드 디렉토리 자체 일 수 있습니다. 다른 사용자/시스템에서는 다를 수 있습니다. 문맥 생성자에 대한 인수로 behat.yml에 다운로드 디렉토리를 전달할 수 있다고 수정하려면 docs을 읽어보십시오.

그러나 가장 좋은 방법은 구성을 Selenium에 전달하여 다운로드 디렉토리를 지정하여 항상 명확하고 정확한 검색 위치를 확인하는 것입니다. 나는 그 일을하는 방법이 확실하지 않지만, quick googling에서 가능할 것으로 보인다.

+0

안녕 이안, 어떻게 다운로드 폴더를 확인합니까. 헤드리스 브라우저 (phantomJS)를 사용하고 있습니다. –

+0

답변을 업데이트했습니다. 나는 당신이 실제 브라우저없이 이것을 할 수있을 것이라고 생각하지 않는다.나는 헤드리스 브라우저를 사용하는 링크를 따라 가면 파일 내용을 반환 할 것이라고 생각 하겠지만, 틀렸을 수도 있습니다. 결코 시도하지 않았습니다. 서로 다른 드라이버에서 둘 이상의 세션을 사용할 수 있습니다. 링크를 따른 후 페이지 콘텐츠가 CSV (다운로드가 작동 중임)인지 확인하거나 다른 세션을 설정하고 적절한 방법으로 확인하십시오. –

2

체크 아웃이 블로그 : https://www.jverdeyen.be/php/behat-file-downloads/

기본적인 아이디어는 현재 세션을 복사 Guzzle에 요청을하는 것입니다. 그 후에 원하는대로 응답을 확인할 수 있습니다. 모든 쿠키를 사용하여와

class FeatureContext extends \Behat\Behat\Context\BehatContext { 

    /** 
    * @When /^I try to download "([^"]*)"$/ 
    */ 
    public function iTryToDownload($url) 
    { 
     $cookies = $this->getSession()->getDriver()->getWebDriverSession()->getCookie('PHPSESSID'); 
     $cookie = new \Guzzle\Plugin\Cookie\Cookie(); 
     $cookie->setName($cookies[0]['name']); 
     $cookie->setValue($cookies[0]['value']); 
     $cookie->setDomain($cookies[0]['domain']); 

     $jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar(); 
     $jar->add($cookie); 

     $client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl()); 
     $client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar)); 

     $request = $client->get($url); 
     $this->response = $request->send(); 
    } 

    /** 
    * @Then /^I should see response status code "([^"]*)"$/ 
    */ 
    public function iShouldSeeResponseStatusCode($statusCode) 
    { 
     $responseStatusCode = $this->response->getStatusCode(); 

     if (!$responseStatusCode == intval($statusCode)) { 
      throw new \Exception(sprintf("Did not see response status code %s, but %s.", $statusCode, $responseStatusCode)); 
     } 
    } 

    /** 
    * @Then /^I should see in the header "([^"]*)":"([^"]*)"$/ 
    */ 
    public function iShouldSeeInTheHeader($header, $value) 
    { 
     $headers = $this->response->getHeaders(); 
     if ($headers->get($header) != $value) { 
      throw new \Exception(sprintf("Did not see %s with value %s.", $header, $value)); 
     } 
    } 
} 
+0

답장을 보내 주셔서 대단히 감사합니다. 나는 곧 그것을 시도 할 것이다. –

+1

어떤 드라이버를 사용하고 있습니까? PhanomJS 드라이버를 사용하여 상태 코드를 지원하지 않는다는 것을 기억합니다. –

0

리틀 수정 iTryToDownload() 함수 : 웹 드라이버와 브라우저 하나와 두 번째 셀레늄 허브 : 프로젝트에서

public function iTryToDownload($link) { 
$elt = $this->getSession()->getPage()->findLink($link); 
if($elt) { 
    $value = $elt->getAttribute('href'); 
    $driver = $this->getSession()->getDriver(); 
    if ($driver instanceof \Behat\Mink\Driver\Selenium2Driver) { 
    $ds = $driver->getWebDriverSession(); 
    $cookies = $ds->getAllCookies(); 
    } else { 
    throw new \InvalidArgumentException('Not Selenium2Driver'); 
    } 

    $jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar(); 
    for ($i = 0; $i < count($cookies); $i++) { 
    $cookie = new \Guzzle\Plugin\Cookie\Cookie(); 
    $cookie->setName($cookies[$i]['name']); 
    $cookie->setValue($cookies[$i]['value']); 
    $cookie->setDomain($cookies[$i]['domain']); 
    $jar->add($cookie); 
    } 
    $client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl()); 
    $client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar)); 

    $request = $client->get($value); 
    $this->response = $request->send(); 
} else { 
    throw new \InvalidArgumentException(sprintf('Could not evaluate: "%s"', $link)); 
} 
} 
0

우리는 우리가 두 개의 서버가 문제가 있습니다. 결과적으로 헤더를 가져 오기 위해 curl 요청을 사용하기로 결정했습니다. 그래서 나는 단계 정의에서 호출 할 함수를 작성했습니다. 당신은 표준 PHP 함수를 사용하는 기능 찾을 수 아래 : curl_init()를

/** 
* @param $request_url 
* @param $userToken 
* @return bool 
* @throws Exception 
*/ 
private function makeCurlRequestForDownloadCSV($request_url, $userToken) 
{ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $request_url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

    $headers = [ 
     'Content-Type: application/json', 
     "Authorization: Bearer {$userToken}" 
    ]; 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 

    $output = curl_exec($ch); 
    $info = curl_getinfo($ch); 
    $output .= "\n" . curl_error($ch); 
    curl_close($ch); 

    if ($output === false || $info['http_code'] != 200 || $info['content_type'] != "text/csv; charset=UTF-8") { 
     $output = "No cURL data returned for $request_url [" . $info['http_code'] . "]"; 
     throw new Exception($output); 
    } else { 
     return true; 
    } 
} 

당신은 내가 토큰에 의해 권한이 볼 수있는 방법. 어떤 헤더를 사용해야하는지 알고 싶다면 파일 수동을 다운로드하고 브라우저의 탭에서 요청과 응답을 봐야합니다. network