<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在上一章最后,我們寫的測試可以算得上是單元測試,接著我們可以寫一些自動化測試。 ## 編寫自動化測試 接著我們就可以用Selenium來做自動化測試。這是ThoughtWorks出品的一個強大的基于瀏覽器的開源自動化測試工具,它通常用來編寫Web 應用的自動化測試。 ### Selenium與第一個UI測試 先讓我們來看一個自動化測試的例子: ~~~ from django.test import LiveServerTestCase from selenium import webdriver class HomepageTestCase(LiveServerTestCase): def setUp(self): self.selenium = webdriver.Firefox() self.selenium.maximize_window() super(HomepageTestCase, self).setUp() def tearDown(self): self.selenium.quit() super(HomepageTestCase, self).tearDown() def test_visit_homepage(self): self.selenium.get( '%s%s' % (self.live_server_url, "/") ) self.assertIn("Welcome to my blog", self.selenium.title) ~~~ 在setUp——即開始的時候,我們會用selenium起一個Firefox瀏覽器的進程,并執行maximize_window來將窗口最大化。在tearDown——即結束的時候,我們就會關閉這個瀏覽器的進程。我們的主要測試代碼就在`test_visit_homepage`這個方法里,我們在里面訪問首頁,并判斷標題是不是`Welcome to my blog`。 運行上面的測試就會啟動一個瀏覽器,并且會在瀏覽器上進行相應的操作。如下圖所示: ![](https://box.kancloud.cn/2016-05-18_573be52850ea3.jpg) Selenium Demo 這時你可能會產生一些疑惑,這些內容我們不是已經測試過了么?兩者從測試看是差不多的,但是從流程上看來說并不是如些。下圖是頁面渲染的時間線: ![](https://box.kancloud.cn/2016-05-18_573be5286b049.png) 頁面渲染時間線 請求從瀏覽器傳到服務器要有一系列的過程,如重定向、緩存、DNS等等,最后直至返回對應的Response。我們用Django的測試框架只能實現到這一步,隨后頁面請請求對應的靜態資料,再對頁面進行渲染,在這個過程中頁面的內容會發生一些變化。 為了避免頁面的內容被替換掉,那么我們就需要對這部分內容進行測試。 如下的代碼也是可以用于測試頁面內容的代碼: ~~~ class BlogpostDetailCase(LiveServerTestCase): def setUp(self): Blogpost.objects.create( title='hello', author='admin', slug='this_is_a_test', body='This is a blog', posted=datetime.now ) self.selenium = webdriver.Firefox() self.selenium.maximize_window() super(BlogpostDetailCase, self).setUp() def tearDown(self): self.selenium.quit() super(BlogpostDetailCase, self).tearDown() def test_visit_blog_post(self): self.selenium.get( '%s%s' % (self.live_server_url, "/blog/this_is_a_test.html") ) self.assertIn("hello", self.selenium.title) ~~~ 雖然在這里我們要測試的只是頁面的標題,而實際上我們要測試的是頁面的元素是否存在。 同樣的,我們也可以對博客的內容進行測試。這些稍有不同的是,我們更多地是要測試用戶的行為,如我們在首頁點擊某個鏈接,那么我應該中轉到對應的博客詳情頁,如下代碼所示: ~~~ class BlogpostFromHomepageCase(LiveServerTestCase): def setUp(self): Blogpost.objects.create( title='hello', author='admin', slug='this_is_a_test', body='This is a blog', posted=datetime.now ) self.selenium = webdriver.Firefox() self.selenium.maximize_window() super(BlogpostFromHomepageCase, self).setUp() def tearDown(self): self.selenium.quit() super(BlogpostFromHomepageCase, self).tearDown() def test_visit_blog_post(self): self.selenium.get( '%s%s' % (self.live_server_url, "/") ) self.selenium.find_element_by_link_text("hello").click() self.assertIn("hello", self.selenium.title) ~~~ 需要注意的是,如果我們的單元測試如果可以測試到頁面的內容——即沒有使用JavaScript對頁面的內容進行修改,那么我們應該使用單元測試即可。如測試金字塔所說,越底層的測試越快。 在我們編寫完這些測試后,我們就可以搭建好相應的持續集成來運行這些測試了。 ## 搭建持續集成 這里我們將使用Jenkins來完成這部分的工具,它是一個用Java編寫的開源的持續集成工具。 > 它提供了軟件開發的持續集成服務。它運行在Servlet容器中(例如Apache Tomcat)。它支持軟件配置管理(SCM)工具(包括AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase和和RTC),可以執行基于Apache Ant和Apache Maven的項目,以及任意的Shell腳本和Windows批處理命令。 要使用Jenkins,只需要從Jenkins的主頁上([https://jenkins.io/](https://jenkins.io/))下載最新的 jenkins.war文件。然后運行 ~~~ java -jar jenkins.war ~~~ 便可以啟動: ~~~ Running from: /Users/fdhuang/repractise/growth-ci/jenkins.war webroot: $user.home/.jenkins May 12, 2016 10:55:18 PM org.eclipse.jetty.util.log.JavaUtilLog info INFO: Logging initialized @489ms May 12, 2016 10:55:18 PM winstone.Logger logInternal INFO: Beginning extraction from war file May 12, 2016 10:55:20 PM org.eclipse.jetty.util.log.JavaUtilLog warn WARNING: Empty contextPath May 12, 2016 10:55:20 PM org.eclipse.jetty.util.log.JavaUtilLog info INFO: jetty-9.2.z-SNAPSHOT May 12, 2016 10:55:20 PM org.eclipse.jetty.util.log.JavaUtilLog info INFO: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet Jenkins home directory: /Users/fdhuang/.jenkins found at: $user.home/.jenkins May 12, 2016 10:55:21 PM org.eclipse.jetty.util.log.JavaUtilLog info INFO: Started w.@68c34b0{/,file:/Users/fdhuang/.jenkins/war/,AVAILABLE}{/Users/fdhuang/.jenkins/war} May 12, 2016 10:55:21 PM org.eclipse.jetty.util.log.JavaUtilLog info INFO: Started ServerConnector@733a9ac6{HTTP/1.1}{0.0.0.0:8080} ~~~ 接著,打開[http://0.0.0.0:8080/](http://0.0.0.0:8080/)就可以進行后續的安裝,如下圖所示: ![](https://box.kancloud.cn/2016-05-18_573be5288ad09.jpg) Jenkins安裝過程 慢慢等其安裝完成: ![](https://box.kancloud.cn/2016-05-18_573be528a8725.jpg) Jenkins安裝完成 等安裝完成后,我們就可以開始使用Jenkins來創建我們的任務了。 ### Jenkins創建任務 在首頁,我們會看到“開始創建一個新任務”的提示,點擊它。 源碼管理中選擇Git,并填入我們代碼的地址: ~~~ [https://github.com/phodal/growth-in-action-python-code](https://github.com/phodal/growth-in-action-python-code) ~~~ 如下圖所示: ![](https://box.kancloud.cn/2016-05-18_573be528cfe2c.jpg) Jenkins設計Repo 然后就是構建觸發器,一共有五種類型的觸發器,意思也很容易理解: * 觸發遠程構建 (例如,使用腳本) * Build after other projects are built * Build periodically * Build when a change is pushed to GitHub * Poll SCM 在這里,我們要使用的是GitHub這個,它的原理是: > This job will be triggered if jenkins will receive PUSH GitHub hook from repo defined in scm section 即Jenkins在監聽GitHub上對應的PUSH hook,當發生代碼提交時,就會運行我們的測試。 由于,我們暫時不需要一些特殊的`構建環境`配置,我們就可以將這個放空。接著,我們就可以配置`構建`了。 ### 創建shell 在這里我們需要添加的構建步驟是:`execute shell`,先讓我們寫一個簡單的安裝依賴的shell ~~~ virtualenv --distribute -p /usr/local/bin/python3.5 growth-django source growth-django/bin/activate pip install -r requirements.txt ~~~ 然后在保存后,我們可以嘗試立即構建這個項目: ![](https://box.kancloud.cn/2016-05-18_573be528f2e4b.jpg) 控制臺輸出 在編寫shell的過程中,我們要經過一些嘗試,在這其中會經歷一些失敗的情形——即使是大部分有相關經驗的程序員。如下圖就是一次編寫構建腳本引起的構建失敗的例子: ![Jenkins失敗的構建](http://growth-in-action.phodal.com/images/jenkins-failure-setup.jpg) Jenkins失敗的構建 最后,我們就得到下面的一個shell腳本,我們就可以將其變成相應的運行CI的腳本。以便于它可以在其他環境中使用: ~~~ #!/usr/bin/env bash virtualenv --distribute -p /usr/local/bin/python3.5 growth-django source growth-django/bin/activate pip install -r requirements.txt python manage.py test python manage.py test test ~~~ 記得給你的shell文件,加上執行的標志: ~~~ chmod u+x ./scripts/ci.sh ~~~ 最后,我們就可以修改CI上相應的構建環境的配置。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看