forked from platformio/platformio-core
Introduce PlatformIO Plus
This commit is contained in:
@ -14,46 +14,7 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import atexit
|
from os.path import join, sep
|
||||||
import sys
|
|
||||||
from os import remove
|
|
||||||
from os.path import isdir, isfile, join, sep
|
|
||||||
from string import Template
|
|
||||||
|
|
||||||
FRAMEWORK_PARAMETERS = {
|
|
||||||
"arduino": {
|
|
||||||
"framework": "Arduino.h",
|
|
||||||
"serial_obj": "",
|
|
||||||
"serial_putc": "Serial.write(a)",
|
|
||||||
"serial_flush": "Serial.flush()",
|
|
||||||
"serial_begin": "Serial.begin(9600)",
|
|
||||||
"serial_end": "Serial.end()"
|
|
||||||
},
|
|
||||||
"mbed": {
|
|
||||||
"framework": "mbed.h",
|
|
||||||
"serial_obj": "Serial pc(USBTX, USBRX);",
|
|
||||||
"serial_putc": "pc.putc(a)",
|
|
||||||
"serial_flush": "",
|
|
||||||
"serial_begin": "pc.baud(9600)",
|
|
||||||
"serial_end": ""
|
|
||||||
},
|
|
||||||
"energia": {
|
|
||||||
"framework": "Energia.h",
|
|
||||||
"serial_obj": "",
|
|
||||||
"serial_putc": "Serial.write(a)",
|
|
||||||
"serial_flush": "Serial.flush()",
|
|
||||||
"serial_begin": "Serial.begin(9600)",
|
|
||||||
"serial_end": "Serial.end()"
|
|
||||||
},
|
|
||||||
"native": {
|
|
||||||
"framework": "stdio.h",
|
|
||||||
"serial_obj": "",
|
|
||||||
"serial_putc": "putchar(a)",
|
|
||||||
"serial_flush": "fflush(stdout)",
|
|
||||||
"serial_begin": "",
|
|
||||||
"serial_end": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def ProcessTest(env):
|
def ProcessTest(env):
|
||||||
@ -69,79 +30,16 @@ def ProcessTest(env):
|
|||||||
env.PioPlatform().get_package_dir("tool-unity"))
|
env.PioPlatform().get_package_dir("tool-unity"))
|
||||||
env.Prepend(LIBS=[unitylib])
|
env.Prepend(LIBS=[unitylib])
|
||||||
|
|
||||||
test_dir = env.subst("$PROJECTTEST_DIR")
|
|
||||||
env.GenerateOutputReplacement(test_dir)
|
|
||||||
src_filter = None
|
src_filter = None
|
||||||
if "PIOTEST" in env:
|
if "PIOTEST" in env:
|
||||||
src_filter = "+<output_export.cpp>"
|
src_filter = "+<output_export.cpp>"
|
||||||
src_filter += " +<%s%s>" % (env['PIOTEST'], sep)
|
src_filter += " +<%s%s>" % (env['PIOTEST'], sep)
|
||||||
|
|
||||||
return env.CollectBuildFiles(
|
return env.CollectBuildFiles(
|
||||||
"$BUILDTEST_DIR", test_dir, src_filter=src_filter, duplicate=False)
|
"$BUILDTEST_DIR",
|
||||||
|
"$PROJECTTEST_DIR",
|
||||||
|
src_filter=src_filter,
|
||||||
def GenerateOutputReplacement(env, destination_dir):
|
duplicate=False)
|
||||||
|
|
||||||
if not isdir(env.subst(destination_dir)):
|
|
||||||
sys.stderr.write(
|
|
||||||
"Error: Test folder does not exist. Please put your test suite "
|
|
||||||
"to \"test\" folder in project's root directory.\n")
|
|
||||||
env.Exit(1)
|
|
||||||
|
|
||||||
TEMPLATECPP = """
|
|
||||||
# include <$framework>
|
|
||||||
# include <output_export.h>
|
|
||||||
|
|
||||||
$serial_obj
|
|
||||||
|
|
||||||
void output_char(int a)
|
|
||||||
{
|
|
||||||
$serial_putc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_flush(void)
|
|
||||||
{
|
|
||||||
$serial_flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_start(unsigned int baudrate)
|
|
||||||
{
|
|
||||||
$serial_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_complete(void)
|
|
||||||
{
|
|
||||||
$serial_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def delete_tmptest_file(file_):
|
|
||||||
try:
|
|
||||||
remove(file_)
|
|
||||||
except: # pylint: disable=bare-except
|
|
||||||
if isfile(file_):
|
|
||||||
print("Warning: Could not remove temporary file '%s'. "
|
|
||||||
"Please remove it manually." % file_)
|
|
||||||
|
|
||||||
if env['PIOPLATFORM'] == "native":
|
|
||||||
framework = "native"
|
|
||||||
else:
|
|
||||||
framework = env.subst("$PIOFRAMEWORK").lower()
|
|
||||||
if framework not in FRAMEWORK_PARAMETERS:
|
|
||||||
sys.stderr.write(
|
|
||||||
"Error: %s framework doesn't support testing feature!\n" %
|
|
||||||
framework)
|
|
||||||
env.Exit(1)
|
|
||||||
else:
|
|
||||||
data = Template(TEMPLATECPP).substitute(FRAMEWORK_PARAMETERS[
|
|
||||||
framework])
|
|
||||||
|
|
||||||
tmp_file = join(destination_dir, "output_export.cpp")
|
|
||||||
with open(tmp_file, "w") as f:
|
|
||||||
f.write(data)
|
|
||||||
|
|
||||||
atexit.register(delete_tmptest_file, tmp_file)
|
|
||||||
|
|
||||||
|
|
||||||
def exists(_):
|
def exists(_):
|
||||||
@ -150,5 +48,4 @@ def exists(_):
|
|||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
env.AddMethod(ProcessTest)
|
env.AddMethod(ProcessTest)
|
||||||
env.AddMethod(GenerateOutputReplacement)
|
|
||||||
return env
|
return env
|
||||||
|
@ -12,20 +12,12 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# pylint: disable=R0913,R0914
|
import sys
|
||||||
|
from os import getcwd
|
||||||
from fnmatch import fnmatch
|
|
||||||
from os import getcwd, listdir
|
|
||||||
from os.path import isdir, join
|
|
||||||
from time import sleep, time
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import serial
|
|
||||||
|
|
||||||
from platformio import exception, util
|
from platformio.pioplus import pioplus_call
|
||||||
from platformio.commands.run import cli as cmd_run
|
|
||||||
from platformio.commands.run import check_project_envs, print_header
|
|
||||||
from platformio.managers.platform import PlatformFactory
|
|
||||||
|
|
||||||
|
|
||||||
@click.command("test", short_help="Unit Testing")
|
@click.command("test", short_help="Unit Testing")
|
||||||
@ -43,220 +35,5 @@ from platformio.managers.platform import PlatformFactory
|
|||||||
writable=True,
|
writable=True,
|
||||||
resolve_path=True))
|
resolve_path=True))
|
||||||
@click.option("--verbose", "-v", is_flag=True)
|
@click.option("--verbose", "-v", is_flag=True)
|
||||||
@click.pass_context
|
def cli(*args, **kwargs): # pylint: disable=unused-argument
|
||||||
def cli(ctx, environment, ignore, upload_port, project_dir, verbose):
|
pioplus_call(sys.argv[1:])
|
||||||
with util.cd(project_dir):
|
|
||||||
test_dir = util.get_projecttest_dir()
|
|
||||||
if not isdir(test_dir):
|
|
||||||
raise exception.TestDirEmpty(test_dir)
|
|
||||||
test_names = get_test_names(test_dir)
|
|
||||||
projectconf = util.load_project_config()
|
|
||||||
assert check_project_envs(projectconf, environment)
|
|
||||||
|
|
||||||
click.echo("Verbose mode can be enabled via `-v, --verbose` option")
|
|
||||||
click.echo("Collected %d items" % len(test_names))
|
|
||||||
|
|
||||||
start_time = time()
|
|
||||||
results = []
|
|
||||||
for testname in test_names:
|
|
||||||
for section in projectconf.sections():
|
|
||||||
if not section.startswith("env:"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
envname = section[4:]
|
|
||||||
if environment and envname not in environment:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# check ignore patterns
|
|
||||||
_ignore = list(ignore)
|
|
||||||
if projectconf.has_option(section, "test_ignore"):
|
|
||||||
_ignore.extend([
|
|
||||||
p.strip()
|
|
||||||
for p in projectconf.get(section, "test_ignore").split(",")
|
|
||||||
if p.strip()
|
|
||||||
])
|
|
||||||
if testname != "*" and \
|
|
||||||
any([fnmatch(testname, p) for p in _ignore]):
|
|
||||||
results.append((None, testname, envname))
|
|
||||||
continue
|
|
||||||
|
|
||||||
cls = (LocalTestProcessor
|
|
||||||
if projectconf.get(section, "platform") == "native" else
|
|
||||||
EmbeddedTestProcessor)
|
|
||||||
tp = cls(ctx, testname, envname, {
|
|
||||||
"project_config": projectconf,
|
|
||||||
"project_dir": project_dir,
|
|
||||||
"upload_port": upload_port,
|
|
||||||
"verbose": verbose
|
|
||||||
})
|
|
||||||
results.append((tp.process(), testname, envname))
|
|
||||||
|
|
||||||
click.echo()
|
|
||||||
print_header("[%s]" % click.style("TEST SUMMARY"))
|
|
||||||
|
|
||||||
passed = True
|
|
||||||
for result in results:
|
|
||||||
status, testname, envname = result
|
|
||||||
status_str = click.style("PASSED", fg="green")
|
|
||||||
if status is False:
|
|
||||||
passed = False
|
|
||||||
status_str = click.style("FAILED", fg="red")
|
|
||||||
elif status is None:
|
|
||||||
status_str = click.style("IGNORED", fg="yellow")
|
|
||||||
|
|
||||||
click.echo(
|
|
||||||
"test:%s/env:%s\t[%s]" % (click.style(
|
|
||||||
testname, fg="yellow"), click.style(
|
|
||||||
envname, fg="cyan"), status_str),
|
|
||||||
err=status is False)
|
|
||||||
|
|
||||||
print_header(
|
|
||||||
"[%s] Took %.2f seconds" % ((click.style(
|
|
||||||
"PASSED", fg="green", bold=True) if passed else click.style(
|
|
||||||
"FAILED", fg="red", bold=True)), time() - start_time),
|
|
||||||
is_error=not passed)
|
|
||||||
|
|
||||||
if not passed:
|
|
||||||
raise exception.ReturnErrorCode()
|
|
||||||
|
|
||||||
|
|
||||||
class TestProcessorBase(object):
|
|
||||||
|
|
||||||
def __init__(self, cmd_ctx, testname, envname, options):
|
|
||||||
self.cmd_ctx = cmd_ctx
|
|
||||||
self.cmd_ctx.meta['piotest_processor'] = True
|
|
||||||
self.test_name = testname
|
|
||||||
self.env_name = envname
|
|
||||||
self.options = options
|
|
||||||
self._run_failed = False
|
|
||||||
|
|
||||||
def print_progress(self, text, is_error=False):
|
|
||||||
click.echo()
|
|
||||||
print_header(
|
|
||||||
"[test::%s] %s" % (click.style(
|
|
||||||
self.test_name, fg="yellow", bold=True), text),
|
|
||||||
is_error=is_error)
|
|
||||||
|
|
||||||
def build_or_upload(self, target):
|
|
||||||
if self.test_name != "*":
|
|
||||||
self.cmd_ctx.meta['piotest'] = self.test_name
|
|
||||||
return self.cmd_ctx.invoke(
|
|
||||||
cmd_run,
|
|
||||||
project_dir=self.options['project_dir'],
|
|
||||||
upload_port=self.options['upload_port'],
|
|
||||||
silent=not self.options['verbose'],
|
|
||||||
environment=[self.env_name],
|
|
||||||
target=target)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def on_run_out(self, line):
|
|
||||||
if line.endswith(":PASS"):
|
|
||||||
click.echo("%s\t[%s]" % (line[:-5], click.style(
|
|
||||||
"PASSED", fg="green")))
|
|
||||||
elif ":FAIL:" in line:
|
|
||||||
self._run_failed = True
|
|
||||||
click.echo("%s\t[%s]" % (line, click.style("FAILED", fg="red")))
|
|
||||||
else:
|
|
||||||
click.echo(line)
|
|
||||||
|
|
||||||
|
|
||||||
class LocalTestProcessor(TestProcessorBase):
|
|
||||||
|
|
||||||
def process(self):
|
|
||||||
self.print_progress("Building... (1/2)")
|
|
||||||
self.build_or_upload(["test"])
|
|
||||||
self.print_progress("Testing... (2/2)")
|
|
||||||
return self.run()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
with util.cd(self.options['project_dir']):
|
|
||||||
pioenvs_dir = util.get_projectpioenvs_dir()
|
|
||||||
result = util.exec_command(
|
|
||||||
[join(pioenvs_dir, self.env_name, "program")],
|
|
||||||
stdout=util.AsyncPipe(self.on_run_out),
|
|
||||||
stderr=util.AsyncPipe(self.on_run_out))
|
|
||||||
assert "returncode" in result
|
|
||||||
return result['returncode'] == 0 and not self._run_failed
|
|
||||||
|
|
||||||
|
|
||||||
class EmbeddedTestProcessor(TestProcessorBase):
|
|
||||||
|
|
||||||
SERIAL_TIMEOUT = 600
|
|
||||||
SERIAL_BAUDRATE = 9600
|
|
||||||
|
|
||||||
def process(self):
|
|
||||||
self.print_progress("Building... (1/3)")
|
|
||||||
self.build_or_upload(["test"])
|
|
||||||
self.print_progress("Uploading... (2/3)")
|
|
||||||
self.build_or_upload(["test", "upload"])
|
|
||||||
self.print_progress("Testing... (3/3)")
|
|
||||||
sleep(1.0) # wait while board is starting...
|
|
||||||
return self.run()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
click.echo("If you don't see any output for the first 10 secs, "
|
|
||||||
"please reset board (press reset button)")
|
|
||||||
click.echo()
|
|
||||||
ser = serial.Serial(
|
|
||||||
self.get_serial_port(),
|
|
||||||
self.SERIAL_BAUDRATE,
|
|
||||||
timeout=self.SERIAL_TIMEOUT)
|
|
||||||
while True:
|
|
||||||
line = ser.readline().strip()
|
|
||||||
|
|
||||||
# fix non-ascii output from device
|
|
||||||
for i, c in enumerate(line[::-1]):
|
|
||||||
if ord(c) > 127:
|
|
||||||
line = line[-i:]
|
|
||||||
break
|
|
||||||
|
|
||||||
if not line:
|
|
||||||
continue
|
|
||||||
self.on_run_out(line)
|
|
||||||
if all([l in line for l in ("Tests", "Failures", "Ignored")]):
|
|
||||||
break
|
|
||||||
ser.close()
|
|
||||||
return not self._run_failed
|
|
||||||
|
|
||||||
def get_serial_port(self):
|
|
||||||
config = self.options['project_config']
|
|
||||||
envdata = {}
|
|
||||||
for k, v in config.items("env:" + self.env_name):
|
|
||||||
envdata[k] = v
|
|
||||||
|
|
||||||
# if upload port is specified manually
|
|
||||||
if self.options.get("upload_port", envdata.get("upload_port")):
|
|
||||||
return self.options.get("upload_port", envdata.get("upload_port"))
|
|
||||||
|
|
||||||
p = PlatformFactory.newPlatform(envdata['platform'])
|
|
||||||
bconfig = p.board_config(envdata['board'])
|
|
||||||
|
|
||||||
port = None
|
|
||||||
board_hwids = []
|
|
||||||
if "build.hwids" in bconfig:
|
|
||||||
board_hwids = bconfig.get("build.hwids")
|
|
||||||
for item in util.get_serialports():
|
|
||||||
if "VID:PID" not in item['hwid']:
|
|
||||||
continue
|
|
||||||
port = item['port']
|
|
||||||
for hwid in board_hwids:
|
|
||||||
hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
|
|
||||||
if hwid_str in item['hwid']:
|
|
||||||
return port
|
|
||||||
if not port:
|
|
||||||
raise exception.PlatformioException(
|
|
||||||
"Please specify `upload_port` for environment or use "
|
|
||||||
"global `--upload-port` option.")
|
|
||||||
return port
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_names(test_dir):
|
|
||||||
names = []
|
|
||||||
for item in sorted(listdir(test_dir)):
|
|
||||||
if isdir(join(test_dir, item)):
|
|
||||||
names.append(item)
|
|
||||||
if not names:
|
|
||||||
names = ["*"]
|
|
||||||
return names
|
|
||||||
|
@ -17,6 +17,7 @@ import click
|
|||||||
from platformio.commands.lib import lib_update as cmd_lib_update
|
from platformio.commands.lib import lib_update as cmd_lib_update
|
||||||
from platformio.commands.platform import platform_update as cmd_platform_update
|
from platformio.commands.platform import platform_update as cmd_platform_update
|
||||||
from platformio.managers.lib import LibraryManager
|
from platformio.managers.lib import LibraryManager
|
||||||
|
from platformio.pioplus import pioplus_update
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
@ -31,6 +32,7 @@ def cli(ctx, only_check):
|
|||||||
click.echo("Platform Manager")
|
click.echo("Platform Manager")
|
||||||
click.echo("================")
|
click.echo("================")
|
||||||
ctx.invoke(cmd_platform_update, only_check=only_check)
|
ctx.invoke(cmd_platform_update, only_check=only_check)
|
||||||
|
pioplus_update()
|
||||||
|
|
||||||
click.echo()
|
click.echo()
|
||||||
click.echo("Library Manager")
|
click.echo("Library Manager")
|
||||||
|
@ -29,6 +29,7 @@ from platformio.commands.platform import platform_update as cmd_platform_update
|
|||||||
from platformio.commands.upgrade import get_latest_version
|
from platformio.commands.upgrade import get_latest_version
|
||||||
from platformio.managers.lib import LibraryManager
|
from platformio.managers.lib import LibraryManager
|
||||||
from platformio.managers.platform import PlatformManager
|
from platformio.managers.platform import PlatformManager
|
||||||
|
from platformio.pioplus import pioplus_update
|
||||||
|
|
||||||
|
|
||||||
def in_silence(ctx):
|
def in_silence(ctx):
|
||||||
@ -140,6 +141,9 @@ def after_upgrade(ctx):
|
|||||||
# pm.update(manifest['name'], "^" + manifest['version'])
|
# pm.update(manifest['name'], "^" + manifest['version'])
|
||||||
pm.update(manifest['name'])
|
pm.update(manifest['name'])
|
||||||
|
|
||||||
|
# update PlatformIO Plus tool if installed
|
||||||
|
pioplus_update()
|
||||||
|
|
||||||
click.secho(
|
click.secho(
|
||||||
"PlatformIO has been successfully upgraded to %s!\n" %
|
"PlatformIO has been successfully upgraded to %s!\n" %
|
||||||
__version__,
|
__version__,
|
||||||
|
53
platformio/pioplus.py
Normal file
53
platformio/pioplus.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Copyright 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from os.path import join
|
||||||
|
|
||||||
|
from platformio import util
|
||||||
|
from platformio.managers.package import PackageManager
|
||||||
|
|
||||||
|
PACKAGE_PIOPLUS_NAME = "tool-pioplus"
|
||||||
|
|
||||||
|
|
||||||
|
class PioPlusPackageManager(PackageManager):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
PackageManager.__init__(
|
||||||
|
self, join(util.get_home_dir(), "packages"),
|
||||||
|
["https://dl.bintray.com/platformio/dl-packages/manifest.json",
|
||||||
|
"https://dl.platformio.org/packages/manifest.json"])
|
||||||
|
|
||||||
|
|
||||||
|
def get_pioplusexe_path():
|
||||||
|
pm = PioPlusPackageManager()
|
||||||
|
package_dir = pm.get_package_dir(PACKAGE_PIOPLUS_NAME)
|
||||||
|
if not package_dir:
|
||||||
|
pm.install(PACKAGE_PIOPLUS_NAME)
|
||||||
|
package_dir = pm.get_package_dir(PACKAGE_PIOPLUS_NAME)
|
||||||
|
assert package_dir
|
||||||
|
return join(package_dir, "pioplus")
|
||||||
|
|
||||||
|
|
||||||
|
def pioplus_update():
|
||||||
|
pm = PioPlusPackageManager()
|
||||||
|
if pm.get_package_dir(PACKAGE_PIOPLUS_NAME):
|
||||||
|
pm.update(PACKAGE_PIOPLUS_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
def pioplus_call(args, **kwargs):
|
||||||
|
os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path()
|
||||||
|
util.copy_pythonpath_to_osenv()
|
||||||
|
subprocess.call([get_pioplusexe_path()] + args, **kwargs)
|
@ -21,6 +21,6 @@ def test_local_env(clirunner, validate_cliresult):
|
|||||||
result = clirunner.invoke(
|
result = clirunner.invoke(
|
||||||
cli_test,
|
cli_test,
|
||||||
["-d", join("examples", "unit-testing", "calculator"), "-e", "local"])
|
["-d", join("examples", "unit-testing", "calculator"), "-e", "local"])
|
||||||
result.exit_code == -1
|
validate_cliresult(result)
|
||||||
assert all(
|
assert all(
|
||||||
[s in result.output for s in ("[PASSED]", "[IGNORED]", "[FAILED]")])
|
[s in result.output for s in ("[PASSED]", "[IGNORED]", "[FAILED]")])
|
||||||
|
9
tox.ini
9
tox.ini
@ -13,7 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py26, py27, docs, lint
|
envlist = py27, docs, lint
|
||||||
|
|
||||||
[testenv:develop]
|
[testenv:develop]
|
||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
@ -53,10 +53,7 @@ commands =
|
|||||||
pylint --rcfile=./.pylintrc ./platformio
|
pylint --rcfile=./.pylintrc ./platformio
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
basepython =
|
basepython = python2.7
|
||||||
py26: python2.6
|
|
||||||
py27: python2.7
|
|
||||||
usedevelop = True
|
|
||||||
passenv = *
|
passenv = *
|
||||||
deps =
|
deps =
|
||||||
pytest
|
pytest
|
||||||
@ -65,8 +62,8 @@ commands =
|
|||||||
py.test -v --basetemp="{envtmpdir}" tests
|
py.test -v --basetemp="{envtmpdir}" tests
|
||||||
|
|
||||||
[testenv:coverage]
|
[testenv:coverage]
|
||||||
passenv = *
|
|
||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
|
passenv = *
|
||||||
deps =
|
deps =
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
Reference in New Issue
Block a user