我正在为我的需求构建一个完全开源的testrunner,但我遇到了一些问题。测试运行器为各种路径中的一组脚本解析yaml文件并执行脚本并使用我将创建的lib来返回结果。现在我有一个简单的ping脚本,我正在努力运行和测试,因为我进步但我收到了很多错误。错误如下,所有源代码也显示在错误下方。
这里的github回购就在这里。随意拉进来测试我看到的问题。 https://github.com/castaway2000/testrunner
问题:
我正在尝试使用我构建的testrunner来解析yaml文件,以获取我正在为我正在使用的项目编写的脚本的路径。
例如,如果想在目标上使用一组特定测试,我可以为每组测试类型创建一个yaml文件。
我遇到了一个问题然而,文件的相对路径和确切路径无法使用django库,导致它无法找到库的路径,除非它从顶层运行django应用程序(即./ping_google.py vs ./testcases/ping_google.py)
但最重要的是,当独立库引用models.py并且admin.py无法从同一目录导入模型时,django应用程序说没有运行。我需要帮助修复和理解这个问题。
这是rundown(stacktrace):
Enterprize:testrunner xwing$ python3 ping_google.py
Traceback (most recent call last):
File "ping_google.py", line 1, in <module>
from testrunnerlib.test import HostInterface
File "/Users/xwing/PycharmProjects/testrunner/testrunnerlib/test.py", line 11, in <module>
from testrunner.models import Host, TestSuite
File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 5, in <module>
class Host(models.Model):
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 105, in __new__
app_config = apps.get_containing_app_config(module)
File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 237, in get_containing_app_config
self.check_apps_ready()
File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 124, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
我在django设置文件中放入导入django和django.setup()之后,上面的错误就消失了但是我收到以下错误:
Enterprize:testrunner xwing$ python3 ping_google.py
Traceback (most recent call last):
File "ping_google.py", line 1, in <module>
from testrunnerlib.test import HostInterface
File "/Users/xwing/PycharmProjects/testrunner/testrunnerlib/test.py", line 11, in <module>
from testrunner.models import Host, TestSuite
File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 5, in <module>
class Host(models.Model):
File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 6, in Host
ip_address = models.CharField(max_length=16)
File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1043, in __init__
super(CharField, self).__init__(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 166, in __init__
self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE
File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
self._wrapped = Settings(settings_module)
File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 97, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "/Users/xwing/PycharmProjects/testrunner/testrunner/settings.py", line 133, in <module>
django.setup()
File "/usr/local/lib/python3.6/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/usr/local/lib/python3.6/site-packages/django/contrib/admin/apps.py", line 23, in ready
self.module.autodiscover()
File "/usr/local/lib/python3.6/site-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
autodiscover_modules('admin', register_to=site)
File "/usr/local/lib/python3.6/site-packages/django/utils/module_loading.py", line 50, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "/Users/xwing/PycharmProjects/testrunner/testrunner/admin.py", line 3, in <module>
from testrunner.models import Host, TestSuite
ImportError: cannot import name 'Host'
修复此问题将有助于测试testrunner的其余构建场景,但我仍然需要有关python需要使用的相对路径和环境的建议,以了解在哪里查找这些库。如果可能的话,我可以将lib放在根python目录中,这样lib就与问题无关。
问题文件:
from testrunnerlib.test import HostInterface
from testrunnerlib.outcomes import Outcomes
from ping3 import ping
def pinger(host):
result = Outcomes()
try:
ping_google = ping(host)
print(ping_google)
if ping_google:
return result.passed()
msg = 'ping had an issue, the following is all we know %s' % ping_google
return result.failed(msg)
except Exception as e:
return result.aborted(exception=e)
if __name__ == '__main__':
pinger(HostInterface().target)
只有django导入的lib:
import yaml
import subprocess
from testrunner.models import Host, TestSuite
class HostInterface(object):
def __init__(self):
self._target = 'not set'
@property
def target(self):
return self._target
@target.setter
def target(self, value):
print("setter of target called", value)
self._target = value
@target.deleter
def target(self):
print("deleter of target called")
del self._target
def host(self):
out = Host.objects.get(id=self.target).name
return out
class YamlInterface:
def __init__(self, yamlfile):
self.file = yamlfile
def handle_yaml(self):
data = TestSuite.objects.get(id=self.file)
yamldata = yaml.safe_load(data.text)
for i in yamldata['testsuite']:
status = subprocess.call('python3 %s' % i, shell=True)
print(status)
def run_tests(host, yaml):
h_interface = HostInterface()
h_interface.target = host
h_interface.host()
yaml = YamlInterface(yaml)
yaml.handle_yaml()
模特:
from __future__ import unicode_literals
from django.db import models
class Host(models.Model):
ip_address = models.CharField(max_length=16)
port = models.IntegerField()
name = models.CharField(max_length=256)
class TestSuite(models.Model):
name = models.CharField(max_length=256)
text = models.TextField()
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "%s" % self.name
admin.py
from django.contrib import admin
from django import forms
from testrunner.models import Host, TestSuite
class HostAdmin(admin.ModelAdmin):
list_display = ['name']
fields = ('name', 'ip_address', 'port')
def __str__(self):
return '%s' % self.name
pass
admin.site.register(Host, HostAdmin)
class TestSuiteAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
formfield = super(TestSuiteAdmin, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'text':
formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
return formfield
admin.site.register(TestSuite, TestSuiteAdmin)
答案 0 :(得分:1)
您需要制作Django管理命令。这将允许您创建允许您使用Django所有功能的脚本。
您可以将此命令作为python3 manage.py ping_google
运行要创建管理命令,
在你的apps文件夹中,创建一个名为management的模块(创建一个名为management的文件夹并在其中放置 init .py文件)
在管理文件夹中,创建一个命令模块(文件夹和 init .py文件)
在命令文件夹中创建ping_google.py文件。
命令是这样写的,
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
help = 'Desc of your command'
def handle(self, *args, **options):
# Your logic goes here
您可以阅读有关自定义django命令here
的更多信息