Если реализации Bar.doesStuff
и Baz.doesStuff
ведут себя по-разному, подходящим решением является наличие двух отдельных тестов.
import org.scalatest.FlatSpec
class FooSpec1 extends FlatSpec {
"a Bar" should "do a bar thing" in {
Bar().doesStuff() == 42
}
"a Baz" should "do a baz thing" in {
Baz().doesStuff() % 2 == 0
}
}
Однако, если они имеют одинаковое поведение, вы можете изменить рефакторинг тестов с помощью функции, чтобы избежать дублирования кода. Я не верю, что scalatest может достичь этого шаблона повторного использования на уровне спецификации, как вы и просили.
import org.scalatest.FlatSpec
class FooSpec2 extends FlatSpec {
def checkDoesStuff(foo: Foo): Boolean =
foo.doesStuff() == 42
"a Bar" should "do a bar thing" in {
checkDoesStuff(Bar())
}
"a Baz" should "do a baz thing" in {
checkDoesStuff(Baz())
}
}
Тем не менее, тестирование на основе свойств может сделать именно то, что вы ищете. Вот пример использования scalacheck:
import org.scalacheck.{Gen, Properties}
import org.scalacheck.Prop.forAll
object FooProperties extends Properties("Foo"){
val fooGen: Gen[Foo] = Gen.pick(1, List(Bar(), Baz())).map(_.head)
property("a Foo always does stuff") = forAll(fooGen){
(foo: Foo) => foo.doesStuff() == 42
}
}
В отличие от спецификаций ScalaTest, свойства всегда являются функциями. Функция forAll
берет генератор, выбирает значения генератора и запускает тест на всех выборках. Наш генератор всегда будет возвращать экземпляр Bar
или Baz
, что означает, что свойство будет охватывать все случаи, которые вы хотите проверить. forAll
утверждает, что если один тест не пройден, все свойство не будет выполнено.
'c:\Program' is not recognized as an internal or external command,
operable program or batch file.
Чтобы получить это сообщение, вы можете:
Использовать shell = True
:
vmrun_cmd = r "c: \ Program Files \ VMware \ VMware Server \ VMware-cmd.bat»
subprocess.Popen (vmrun_cmd, shell = True)
Изменение vmrun_cmd в другой части вашего кода
Попытка:
Откройте приглашение python и выполните следующую команду:
subprocess. Popen ([r "c: \ Program Files \ VMware \ VMware Server \ vmware-cmd.bat"])
Если это работает, то о проблемах цитирования не может быть и речи. Если нет, то вы изолировали проблему.
В Python в MS Windows класс subprocess.Popen использует API CreateProcess для запуска процесса. CreateProcess принимает строку, а не что-то вроде массива аргументов. Python использует subprocess.list2cmdline для преобразования списка аргументов в строку для CreateProcess.
На вашем месте я бы посмотрел, что возвращает subprocess.list2cmdline (args) (где args - первый аргумент Popen). Было бы интересно посмотреть, ставит ли он кавычки вокруг первого аргумента.
Конечно, это объяснение может не применяться в среде Cygwin.
С учетом всего этого у меня нет MS Windows.
Я считаю, что list2cmdline (), который выполняет обработку из вашего списка аргументов, разделяет любые строковые аргументы в пробелах, если строка не содержит двойных кавычек. Поэтому я ожидаю, что
vmrun_cmd = r'"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"'
будет тем, что вы хотите.
Вы также, вероятно, захотите заключить другие аргументы (например, target_vm
) в двойные кавычки, предполагая, что они тоже представляют каждый отличный аргумент для представления в командной строке. Подойдет что-то вроде
r'"%s"' % target_vm
(например).
D '
2 вещи
1)
Возможно, вы не хотите использовать Pipe Если выходные данные подпрограммы превышают 64 КБ, скорее всего, ваш процесс завершится сбоем. http://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/ [тысяча двести двадцать-три] 2) Subprocess.Popen имеет ключевое слово аргумент shell, делающий так, как будто оболочка анализирует ваши аргументы, установка shell = True должна делать то, что вы хотите.
Почему вы используете r ""? Я считаю, что если вы удалите «r» с самого начала, он будет рассматриваться как стандартная строка, которая может содержать пробелы. Затем Python должен правильно заключать строку в кавычки при отправке в оболочку.
Возможно, глупое предложение, но, возможно, попробуйте следующее, чтобы удалить подпроцесс + пробелы из уравнения:
import os
from subprocess Popen, PIPE
os.chdir(
os.path.join("C:", "Program Files", "VMware", "VMware Server")
)
p = Popen(
["vmware-cmd.bat", target_vm, list_arg, list_arg2],
stdout=PIPE
).communicate()[0]
Возможно, стоит попробовать.
p = Popen(
[os.path.join("C:", "Program Files", "VMware", "VMware Server", "vmware-cmd.bat"), ...
Here's what I don't like
vmrun_cmd = r"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"
You've got spaces in the name of the command itself -- which is baffling your shell. Hence the "'c:\Program' is not recognized as an internal or external command, работоспособная программа или пакетный файл. "
Вариант 1 - поместите свой файл .BAT куда-нибудь еще. Действительно, поместите все свои VMWare в другое место. Вот правило: Не используйте каталог" Program Files "для чего-либо. Это просто неправильно.
Вариант 2 - процитировать значение vmrun_cmd
vmrun_cmd = r'"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"'
Если у вас есть пробелы в пути, я нашел самый простой способ правильно их интерпретировать:
subprocess.call('""' + path + '""')
Я не знаю, почему именно для этого нужны двойные двойные кавычки, но это то, что работает.
Одна проблема заключается в том, что если команда заключена в кавычки и не содержит пробелов, это также может сбить с толку оболочку.
Итак, я делаю следующее:
if ' ' in raw_cmd:
fmt = '"%s"'
else:
fmt = '%s'
cmd = fmt % raw_cmd