【问题标题】:Selenium keeps a cache? Why my javascript isn't loaded in tests?Selenium 保持缓存?为什么我的 javascript 没有在测试中加载?
【发布时间】:2019-10-30 17:29:19
【问题描述】:

我有一个更复杂的问题,但我正在尝试隔离问题以避免混淆。

我正在使用 selenium 测试一个页面。在此页面中有两个 javascript 外部脚本。如果你手动去那里,页面工作正常,但使用 selenium 没有加载其中一个 javascript:

The script from “http://localhost:55234/static/js/common.js” was loaded even though its MIME type (“text/html”) is not a valid JavaScript MIME type.
2 add-name
Loading failed for the <script> with source “http://localhost:55234/static/js/common.js”.

检查源代码(右键单击 => 查看页面源代码)正确地为我提供了带有这两行的模板(当然还有其他行):

[...] 
<!-- load global javascript -->
    <script type='text/javascript' src="/static/js/common.js"></script>
<!-- load app javascript -->
  <script type='text/javascript' src="/static/lists/js/lists.js"></script>
[...]

src 是可点击的。单击第一个重新加载源页面没有第三和第四行,所以没有这行:

<!-- load app javascript -->
  <script type='text/javascript' src="/static/lists/js/lists.js"></script>

单击第二个 (lists.js) 会给出 javascript 代码。但!但是这段代码看起来是我的代码的(非常)旧版本。很多天了(缓存时间不会太长吗?)。当时所有代码都在一个 javascript 文件 (lists.js) 中,而另一个 (common.js) 不存在,所以这可以解释为什么没有加载。

这是为什么呢?如何更新此代码?如果我手动进入页面,我可以找到真正的更新代码。

还可以知道,在我的浏览器中,我最近在网络选项卡中选择了“禁用缓存”(使用 firefox 按 F12)和设置中的“禁用 HTTP 缓存 (...)”,只是为了避免这些问题。在 selenium 打开的页面中,这些选项都未选中。我尝试检查两者(使用断点())并重新加载页面,但没有任何改变。

我再说一遍,也许这是其他地方的原因,还有很多其他的事情要说,但我认为最好让事情尽可能简单,并在需要时提出其他问题。现在,这有什么意义吗?为什么我的脚本在几天内没有更新(如果可能,我宁愿不清空缓存)?

我找到了删除缓存的代码,我应该试试吗?看起来对吗?

def setUp(self):
    profile = webdriver.FirefoxProfile()
    profile.set_preference("browser.cache.disk.enable", False)
    profile.set_preference("browser.cache.memory.enable", False)
    profile.set_preference("browser.cache.offline.enable", False)
    profile.set_preference("network.http.use-cache", False)
    self.browser = webdriver.Firefox(profile)

这里有一些代码:

我的模板base.html

[...]
<head>
  [...]
  <!-- load global javascript -->
  <script type='text/javascript' src="{% static '/js/common.js' %}"></script>
  <!-- load app javascript -->
  {% block script %}{% endblock %}
[...]

我的模板列表.html

{% block script %}
  <script type='text/javascript' src="{% static 'lists/js/lists.js' %}"></script>
{% endblock %}

其中common.jsmyproject/static/js/common.js 中,而lists.jsmyproject/lists/static/lists/js/lists.js 中。我都用{% static 打电话,但它应该是正确的。

我的test.py

class NameFormSeleniumTest(LiveServerTestCase):
    def setUp(self):
        self.browser = webdriver.Firefox()
        self.browser.implicitly_wait(2)

    def tearDown(self):
        self.browser.quit()

    def test_form_can_save_a_name(self):
    # some code
    # english = ...
    self.browser.get(self.live_server_url + '/lists/add-name/')
    Select(self.browser.find_element_by_id('id_namelanguage')).\
        select_by_value(str(english.id))
    # ...
    breakpoint()
    form = NameForm({'nametype': nome.id, 'gender': maschio.id,
                     'name': 'Remo', 'namelanguage': english.id,
                     'usato': 0})
    print(form.errors)
    form.save()

测试给出的错误是(在form = ... 行中):

ValueError: The Name could not be created because the data didn't validate.

form.error 是:

<ul class="errorlist"><li>nametype<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

但是对于breakpoint(),我看到找不到向字段添加选项的javascript函数,该字段保持为空,因此Select()不要选择任何内容,并且表单给出了错误。

感谢您的帮助

【问题讨论】:

  • 我认为这与浏览器缓存无关。看起来本地 Web 服务器在需要 text/javascript 时没有返回具有 text/html mime 类型的 JavaScript 文件。检查服务器配置以确保为 .js 文件正确配置 mime 类型。
  • 除非您将 Selenium 设置为每次都使用某个配置文件,否则每次运行都会有一个新的缓存。 (这是一个很好的测试用例!)听起来您的手动方法是从缓存中提取的方法。
  • @GregBurghardt 我正在使用 django 服务器(manage.py runserver),如果我手动去那里它就可以工作(我的意思是像最终用户一样使用浏览器导航)。问题可能出在其他地方,但为什么我看到的是旧的 javascript 文件?它从哪里来?它在我的电脑上不再存在(好吧,也许在一些旧的 git 存储库中)
  • @pcalkins 不,我没有设置硒的配置文件。你说的最后一句话是什么意思?抱歉,我是新手,我不明白哪个可以是我的“手动方法”。我有更多的测试文件,即使在这个测试文件中我也有更多的类,但我认为不会从缓存中提取任何内容(而且我不知道该怎么做)。在我在这个类中跳过的代码中,我只是创建了填充表单的对象。
  • 我补充说,我在另一个测试中遇到了同样的加载脚本问题,这不是针对服务器的,而是针对代码中的一些错误:如果代码不正确,硒不会加载脚本并给出 MIME 错误(当然也可能有其他原因)。不幸的是,我不记得那个时候哪个代码给了我问题,可能是测试代码。我不确定是否可以使用 selenium 以这种方式调用表单

标签: javascript django selenium caching django-staticfiles


【解决方案1】:

我发现了问题。

来自documentation

当运行使用实际 HTTP 请求而不是内置测试客户端的测试时(即使用内置 LiveServerTestCase 时),静态资产需要与其余内容一起提供,以便测试环境重现真实资产尽可能忠实,但 LiveServerTestCase 仅具有非常基本的静态文件服务功能:它不了解 staticfiles 应用程序的查找器功能,并假定静态内容已在 STATIC_ROOT 下收集。

正因为如此,staticfiles 提供了自己的 django.contrib.staticfiles.testing.StaticLiveServerTestCase,一个 具有透明能力的内置子类 在执行这些测试期间以非常好的方式服务所有资产 类似于我们在开发时使用 DEBUG = True 得到的,即 无需先使用 collectstatic 收集它们。

所以它正在加载我的 javascript 脚本的旧版本。如您所见,解决方案是使用StaticLiveServerTestCase 而不是LiveServerTestCase

【讨论】:

    猜你喜欢
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    相关资源
    最近更新 更多