postcon / behat-shell-extension
一个用于远程和本地执行shell命令的Behat扩展
Requires
- php: >=5.4
- behat/behat: ^3.0
- symfony/process: ^2.6|~3.0
Requires (Dev)
- phpunit/phpunit: ^4.0
This package is auto-updated.
Last update: 2024-09-23 22:53:25 UTC
README
Behat扩展,用于在特性内执行shell命令。shell命令可以在使用ssh的远程服务器上运行,也可以在没有网络的本地运行。此外,可以将本地文件部署到远程服务器上的目录。
安装
使用composer
composer require postcon/behat-shell-extension dev-master
使用方法
# run.feature Feature: Running commands In order to run useful integration tests As a tester I want to execute shell commands and check their output Scenario: Run command on the default shell/server and define expected output When I run "pwd" Then It should pass And I see """ /tmp """ Scenario: Run command on the default shell/server and define expected output in inline-style When I run "pwd" Then It should pass And I see "/tmp" Scenario: Run command on the shell/server "app" When I run "app/console --env=prod do:mi:mi" on "app" Then It should pass
# copy.feature Feature: Copy file In order to prepare integration tests As a tester I want to copy files to directories (on remote servers) Scenario: Copy a file to /tmp directory on default server (or at the local filesystem) Given I copy file "test.txt" to "/tmp" And I run "cat /tmp/test.txt" Then it should pass And I see """ content of test.txt """ Scenario: Copy a file to /tmp directory on "app" server Given I copy file "test.txt" to "/tmp" on "app" And I run "cat /tmp/test.txt" on "app" Then it should pass And I see """ content of test.txt """
配置
要使用BehatShellExtension,需要在behat.yml
(或behat.yml.dist
)中进行配置。您想调用命令的每个服务器或shell都必须指定。
本地shell
以下示例显示了本地shell的最小配置。
# behat.yml extensions: ShellExtension: default: type: local
可以提供两个额外的配置参数:命令执行的base_dir
和timeout
(秒;如果命令未在超时时间内终止,则将其停止,Behat特性失败)。
# behat.yml extensions: ShellExtension: default: type: local base_dir: /tmp timeout: 10
远程服务器/ssh
要通过ssh访问远程服务器,最小配置如下
# behat.yml extensions: ShellExtension: ... app: type: remote ssh_hostname: user@shell.example.com
ssh_hostname
指定ssh服务器名称和用户名。使用附加参数,可以配置ssh连接,并指定ssh和scp二进制文件。
# behat.yml extensions: ShellExtension: ... app: type: remote base_dir: /tmp ssh_hostname: user@shell.example.com ssh_options: -i ~/.ssh/id_rsa ssh_command: /usr/bin/ssh scp_command: /usr/bin/scp timeout: 20
如果我们有这个特性示例
Scenario:
Given I copy file "test.txt" to "/tmp" on "app"
And I run "cat /tmp/test.txt" on "app"
则生成的命令如下
/usr/bin/scp -i ~/.ssh/id_rsa 'test.txt' 'user@shell.example.com:/tmp'
/usr/bin/ssh -i ~/.ssh/id_rsa user@shell.example.com 'cd /tmp ; cat /tmp/test.txt'
Docker
要在Docker容器中执行命令,以下最小配置是合适的
# behat.yml extensions: ShellExtension: ... app: type: docker docker_containername: app
这里,我们假设有一个这样的Docker容器
docker run --name=app -d nginx
以下是一个更详细的配置
# behat.yml extensions: ShellExtension: ... app: type: docker base_dir: /tmp docker_containername: app docker_command: /usr/local/bin/docker docker_options: -u user timeout: 20
这里,给出了docker执行程序的位置,以及如果需要的话,给出了options。
如果我们有这个特性示例
Scenario:
Given I copy file "test.txt" to "/tmp" on "app"
And I run "cat /tmp/test.txt" on "app"
则生成的命令如下
/usr/local/bin/docker cp 'test.txt' app:'/tmp'
/usr/local/bin/docker exec -u user app /bin/bash -c 'cd /tmp ; cat /tmp/test.txt'
Docker-Compose
通过更改docker_command
参数,可以使用docker-compose服务而不是Docker容器
# behat.yml extensions: ShellExtension: app: type: docker base_dir: /tmp docker_containername: app docker_command: /usr/local/bin/docker-compose docker-options: -T timeout: 20
重要的是要指定docker-options: -T
以“禁用伪终端分配”。
这里,我们假设有一个这样的Docker-compose配置
# docker-compose.yml version: '2' services: app: image: php:7.1-fpm
目前,无法将文件复制到正在运行的docker-compose服务中(即缺少命令docker-compose cp
)。
内部实现
在shell上执行$command
命令字符串,当类型为local
时,会以以下方式调用
$process = new Process($command, $serverConfig['base_dir']); $process->setTimeout($serverConfig['timeout']); $process->run();
以这种方式执行远程执行的命令字符串$command
if ($serverConfig['base_dir']) { $command = sprintf('cd %s ; %s', $serverConfig['base_dir'], $command); } $command = sprintf( '%s %s %s %s', $serverConfig['ssh_command'], $serverConfig['ssh_options'], $serverConfig['ssh_hostname'], escapeshellarg($command) ); // e.g. ssh -i ~/.ssh/id_rsa user@shell.example.com 'cd /var/www ; app/console --env=prod do:mi:mi' $process = new Process($command); $process->setTimeout($serverConfig['timeout']); $process->run();
当使用docker时,以这种方式执行命令字符串$command
if ($serverConfig['base_dir']) { $command = sprintf('cd %s ; %s', $serverConfig['base_dir'], $command); } $command = sprintf( '%s exec %s /bin/bash -c %s', $serverConfig['docker_command'], $serverConfig['docker_containername'], escapeshellarg($command) ); // e.g. docker exec container /bin/bash -c 'cd /var/www ; app/console --env=prod do:mi:mi' $process = new Process($command); $process->setTimeout($serverConfig['timeout']); $process->run();
许可证
本包所有内容均受MIT许可证许可。