Laravel 測試: PHPUnit 入門教程

介紹 PHPUnit 測試的基礎知識,使用基本的 PHPUnit 斷言和 Laravel 測試助手。

介紹

PHPUnit?是最古老和最著名的 PHP 單元測試包之一。它主要用于單元測試,這意味著可以用盡可能小的組件測試代碼,但是它也非常靈活,可以用于很多不僅僅是單元測試。

PHPUnit 包含許多簡單和靈活的斷言允許您輕松地測試代碼,當您測試特定的組件時,這些斷言非常有效。但是,它確實意味著測試更高級的代碼(如控制器和表單提交驗證)可能會復雜得多。

為了幫助開發人員更容易地進行開發, Laravel 框架 ?包含了一系列 應用程序測試幫助程序 ,允許您編寫非常簡單的 PHPUnit 測試來測試應用程序的復雜部分。

本教程的目的是向您介紹 PHPUnit 測試的基礎知識,使用默認 PHPUnit 斷言和 Laravel 測試助手。這樣做的目的是在本教程結束時,您可以自信地為應用程序編寫基本測試。

前提

本教程假設您已經熟悉 Laravel 并知道如何在應用程序目錄中運行命令(例如?php artisan?命令)。我們將創建幾個基本的示例類來學習不同的測試工具如何工作,因此建議您為本教程創建一個新的應用程序。

如果已經安裝了 Laravel ,則可以通過運行以下命令創建新的測試應用程序:

laravel new phpunit-tests復制代碼

或者,您可以直接使用?Composer?創建新應用程序:

composer create-project laravel/laravel --prefer-dist復制代碼

其他安裝方法也可以在?Laravel 文檔中找到。

創建一個新的測試

使用 PHPUnit 的第一步是創建一個新的測試類。測試類的約定是它們存儲在應用程序目錄的?./tests/?下。在這個文件夾中,每個測試類都被命名為?<name>Test.php 。這種格式允許 PHPUnit 查找每個測試類---它將忽略任何不以?Test.php 結尾的文件。

在新的 Laravel 應用程序中,你會注意到?./tests/?目錄中有兩個文件: ?ExampleTest.php?和?TestCase.php. ?TestCase.php?文件是一個引導文件用于在我們的測試中設置 Laravel 環境。這允許我們在測試中使用 Laravel Facades 并為測試助手提供框架,我們將在稍后介紹。?ExampleTest.php?是一個示例測試類,其中包含使用應用程序測試助手的基本測試用例-暫時忽略它。

要創建一個新的測試類,我們可以手動創建一個新文件,或者運行由 Laravel 提供的 Artisan 命令?make:test

為了創建一個名為?BasicTest 的測試類,我們只需要運行這個 artisan 命令:

php artisan make:test BasicTest復制代碼

Laravel 將創建一個如下所示的基本測試類:

<?php
class BasicTest extends TestCase
{/*** 一個基本的測試示例。** @return void*/public function testExample(){$this->assertTrue(true);}
}復制代碼

這里要注意的最重要的事情是?test?方法名稱上的前綴,與?Test 類名后綴一樣,這樣?test?前綴告訴 PHPUnit 在測試時運行哪些方法。如果您忘記了?test?前綴,那么 PHPUnit 將忽略該方法。

在我們第一次運行測試套件之前,有必要指出 Laravel 提供的默認?phpunit.xml 文件。 PHPUnit 在運行時會自動在當前目錄中查找名為 phpunit.xml?或者?phpunit.xml.dist?的文件。您可以在此處配置測試的特定選項。

這個文件中有很多信息,但是現在最重要的部分是在?testsuite?目錄定義:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit ... ><testsuites><testsuite name="Application Test Suite"><directory>./tests/</directory></testsuite></testsuites>...
</phpunit>復制代碼

這將告訴 PHPUnit 運行時在?./tests/?目錄中找到的測試,正如我們之前所知,這是存儲測試的約定。

現在我們已經創建了一個基本測試,并且知道了 PHPUnit 配置,現在是第一次運行測試的時候了。

您可以通過運行以下?phpunit?命令來運行測試:

./vendor/bin/phpunit復制代碼

您應該看到與此類似的輸出:

PHPUnit 4.8.19 by Sebastian Bergmann and contributors...Time: 103 ms, Memory: 12.75MbOK (2 tests, 3 assertions)復制代碼

現在我們已經有了一個有效的 PHPUnit 設置,現在是時候開始編寫一個基本測試了。

注意,它會統計2個測試和3個斷言,因為?ExampleTest.php?文件包含了一個帶有兩個斷言的測試。我們的新基本測試包括一個單獨的斷言,該斷言已通過。

寫一個基礎測試

為了幫助 PHPUnit 提供的基本斷言,我們將首先創建一個提供一些簡單功能的基本類

在?./app/?目錄中創建一個名為?Box.php 的新文件,并復制此示例類:

<?php
namespace App;class Box
{/*** @var array*/protected $items = [];/*** 使用給定項構造框** @param array $items*/public function __construct($items = []){$this->items = $items;}/*** 檢查指定的項目是否在框中。** @param string $item* @return bool*/public function has($item){return in_array($item, $this->items);}/*** 從框中移除項,如果框為空,則為 null 。** @return string*/public function takeOne(){return array_shift($this->items);}/*** 從包含指定字母開頭的框中檢索所有項目。** @param string $letter* @return array*/public function startsWith($letter){return array_filter($this->items, function ($item) use ($letter) {return stripos($item, $letter) === 0;});}
}復制代碼

接下來, 打開你的?./tests/BasicTest.php?類(我們之前創建的類),并刪除默認創建的?testExample?方法, 你應該留一個空類。

我們現在將使用七個基本的 PHPUnit 斷言來為我們的?Box?類編寫測試。這些斷言是:

  • assertTrue()
  • assertFalse()
  • assertEquals()
  • assertNull()
  • assertContains()
  • assertCount()
  • assertEmpty()

assertTrue() 和 assertFalse()

assertTrue()?和?assertFalse()?允許你聲明一個值等于 true 或 false 。這意味著它們非常適合測試返回布爾值的方法。在我們的?Box 類中,我們有一個名為?has($item) 的方法,當指定的項在 box 中或不在 box 中時,該方法返回對應返回 true 或 false .

要在 PHPUnit 中為此編寫測試,我們可以執行以下操作:

<?php
use App\Box;class BasicTest extends TestCase
{public function testHasItemInBox(){$box = new Box(['cat', 'toy', 'torch']);$this->assertTrue($box->has('toy'));$this->assertFalse($box->has('ball'));}
}復制代碼

注意我們如何只將一個參數傳遞給?assertTrue()?和?assertFalse()?方法,并且它是?has($item)?方法的輸入.

如果您現在運行?./vendor/bin/phpunit?命令,您會注意到輸出包括:

OK (2 tests, 4 assertions)復制代碼

這意味著我們的測試已經通過。

如果您將?assertFalse()?替換成?assertTrue()?并運行?phpunit?命令,輸出將如下所示:

PHPUnit 4.8.19 by Sebastian Bergmann and contributors.F.Time: 93 ms, Memory: 13.00MbThere was 1 failure:1) BasicTest::testHasItemInBox
Failed asserting that false is true../tests/BasicTest.php:12FAILURES!
Tests: 2, Assertions: 4, Failures: 1.復制代碼

這告訴我們第12行的斷言未能斷言?false?值是?true?- 因為我們將?assertFalse()?替換為?assertTrue()

將其交換回來,然后重新運行 PHPUnit 。測試應該再次通過,因為我們已經修復了破損的測試。

assertEquals() 與 assertNull()

接下來,讓我們看看?assertEquals(), 以及?assertNull()

assertEquals() 用于比較變量實際值與預期值是否相等。我們用它來檢查 takeOne() 方法的返回值是否為 Box 內的當前值。當 Box 為空時,takeOne() 將返回 null,我們亦可使用 assertNull() 來進行檢查。

與?assertTrue()assertFalse() 以及?assertNull() 不同,assertEquals()?需要兩個參數。第一個參數為 預期 值,第二個參數則為 實際 值。

可參照如下代碼實現以上斷言(assertions):

<?php
use App\Box;class BasicTest extends TestCase
{public function testHasItemInBox(){$box = new Box(['cat', 'toy', 'torch']);$this->assertTrue($box->has('toy'));$this->assertFalse($box->has('ball'));}public function testTakeOneFromTheBox(){$box = new Box(['torch']);$this->assertEquals('torch', $box->takeOne());// 當前 Box 為空,應當為 Null$this->assertNull($box->takeOne());}
}復制代碼

運行?phpunit?命令,你應當看到如下輸出:

OK (3 tests, 6 assertions)復制代碼

assertContains() 和 assertCount() 以及 assertEmpty()

終于,我們有三個作用于數組有關的斷言,我們能夠使用它們去檢查?Box?類中的 ?startsWith($item) 方法。?assertContains()?斷言傳遞進來的數組中包含指定值,?assertCount()?斷言數組的項數為指定數量,assertEmpty() 斷言傳遞進來的數組為空。

讓我們來執行以下測試:

<?php
use App\Box;class BasicTest extends TestCase
{public function testHasItemInBox(){$box = new Box(['cat', 'toy', 'torch']);$this->assertTrue($box->has('toy'));$this->assertFalse($box->has('ball'));}public function testTakeOneFromTheBox(){$box = new Box(['torch']);$this->assertEquals('torch', $box->takeOne());// Null,現在這個 box 是空的。$this->assertNull($box->takeOne());}public function testStartsWithALetter(){$box = new Box(['toy', 'torch', 'ball', 'cat', 'tissue']);$results = $box->startsWith('t');$this->assertCount(3, $results);$this->assertContains('toy', $results);$this->assertContains('torch', $results);$this->assertContains('tissue', $results);// 如果傳遞復數斷言數組為空$this->assertEmpty($box->startsWith('s'));}
}復制代碼

保存并再一次運行你的測試:

OK (4 tests, 9 assertions)復制代碼

恭喜你,你剛剛使用七個基礎的 PHPUnit 斷言完成了對 Box 類的全部測試。通過這些簡單的斷言你能夠做許多事,對于其他斷言,大多數要更復雜,不過它們仍遵循以上使用規則。

測試你的程序

在你的程序里,對每個組件進行單元測試在很多情況下都是有必要的,而且也應該成為你開發過程中必不可少的一部分,但這并不是你需要做的全部的測試。當你構建一個包含復雜視圖、導航和表單的程序時,你同樣想測試這些組件。這時,Laravel的測試助手可以使這些測試像單元測試簡單組件一樣容易。

我們之前查看在?./tests/?目錄下的默認文件時跳過了 ./tests/ExampleTest.php?文件。 現在打開它,內容如下所示:

<?php
class ExampleTest extends TestCase
{/**
* 一個基本功能測試示例。
*
* @return void
*/public function testBasicExample(){$this->visit('/')->see('Laravel 5');}
}復制代碼

我們可以看到這個測試示例非常簡單。在不知道測試助手如何運作的情況下,我們可以猜測它的意思如下:

  1. 當我訪問/?(根目錄)
  2. 我應該看到 'Laravel 5'

如果你打開你的web瀏覽器,訪問我們的程序(如果你沒有啟動你的web服務器,你可以運行?php artisan serve?),你應該可以在web根目錄上看到屏幕上有“Laravel 5”的文本。 鑒于這個測試已經通過了PHPUnit,我們可以很確定地說我們對這個測試示例改造是正確的。

這個測試確保了訪問/路徑,網頁可以返回“'Laravel 5”的文本。一個如此簡單的檢查也許不代表什么,但如果你的網站上要顯示關鍵信息,它就可以在一個別處的改動導致這個頁面無法正常顯示正確的信息時,防止你部署一個被損壞的程序。

visit()、see() 以及 dontSee()

現在嘗試編寫自己的測試,更進一步理解它吧。

首先,編輯?./app/Http/routes.php?,增加一個新的路由。為了教程目的,我們創建希臘字母定義的路由:

<?php
Route::get('/'function () {return view('welcome');
});Route::get('/alpha'function () {return view('alpha');
});復制代碼

然后,創建視圖文件?./resources/views/alpha.blade.php,使用 Alpha 作為關鍵字,保存基本的HTML文件:

<!DOCTYPE html>
<html><head><title>Alpha</title></head><body><p>This is the Alpha page.</p></body>
</html>復制代碼

打開瀏覽器,輸入網址:?http://localhost:8000/beta,頁面會顯示出 "This is the Alpha page." 的內容。

現在我們有了測試用到的模版文件,下一步,我們通過運行命令?make:test?來創建一個新的測試文件:

php artisan make:test AlphaTest復制代碼

然后變成剛創建好的測試文件,按照框架提供的例子,測試 "alpha" 頁面上沒有包含 "beta" 。 我們可以使用方法?dontSee()?,它是?see() 的對應的反向方法。

下面代碼是上面實現的簡單例子:

<?php
class AlphaTest extends TestCase
{public function testDisplaysAlpha(){$this->visit('/alpha')->see('Alpha')->dontSee('Beta');}
}復制代碼

保存并運行 PHPUnit (./vendor/bin/phpunit),測試代碼應該會全部通過,你會看到像這樣的測試狀態內容顯示:

OK (5 tests,12 assertions)復制代碼

開發前先寫測試

對于測試來說,測試驅動開發?(TDD) 是非常酷的方法,首先我們先寫測試。寫完測試并執行它們,你會發現測試沒通過,接下來?我們編寫滿足測試的代碼,再次執行測試,使測試通過。 接下來讓我們開始。

首先,建立一個?BetaTest?類使用?make:test?artisan 命令:

php artisan make:test BetaTest復制代碼

接下來,更新測試用例以便檢查?/beta?的路由 route 為「Beta」:

<?php
class BetaTest extends TestCase
{public function testDisplaysBeta(){$this->visit('/beta')->see('Beta')->dontSee('Alpha');}
}復制代碼

現在使用?./vendor/bin/phpunit 命令來執行測試。結果是一個看起來簡潔但不好的錯誤信息,如下:

> ./vendor/bin/phpunit
PHPUnit 4.8.19 by Sebastian Bergmann and contributors.....F.Time: 144 ms, Memory: 14.25MbThere was 1 failure:1) BetaTest::testDisplaysBeta
一個對 [http://localhost/beta] 的請求失敗了。收到狀態碼 [404]。...FAILURES!
Tests: 6, Assertions: 13, Failures: 1.復制代碼

我們現在需要創建這個不存在的路由。讓我們開始。

首先,編輯?./app/Http/routes.php?文件來創建新的 /beta?路由:

<?php
Route::get('/', function () {return view('welcome');
});Route::get('/alpha', function () {return view('alpha');
});Route::get('/beta', function () {return view('beta');
});復制代碼

接下來,在 ./resources/views/beta.blade.php 下創建如下視圖模版:

<!DOCTYPE html>
<html><head><title>Beta</title></head><body><p>This is the Beta page.</p></body>
</html>復制代碼

現在再一次執行 PHPUnit,結果應該再一次回到綠色。

> ./vendor/bin/phpunit
PHPUnit 4.8.19 by Sebastian Bergmann and contributors.......Time: 142 ms, Memory: 14.00MbOK (6 tests, 15 assertions)復制代碼

這樣我們就通過在完成新的頁面之前寫測試的方式,對 測試驅動開發 進行了實踐。

click() 和 seePageIs()

Laravel 也提供一個輔助函數 (click()) 允許測試點擊頁面中存在的連接 ,以及一個方法 (seePageIs()) 檢查點擊展示的結果頁面。

讓我們使用這兩個輔助函數去執行在 Alpha 和 Beta 頁面的鏈接。

首先,我們更新我們的測試。打開?AlphaTest?類,我們將添加一個新的測試方法,這將點擊 「alpha」頁面上的「Next」鏈接跳轉到 「beta」頁面。

新的測試代碼如下:

<?php
class AlphaTest extends TestCase
{public function testDisplaysAlpha(){$this->visit('/alpha')->see('Alpha')->dontSee('Beta');}public function testClickNextForBeta(){$this->visit('/alpha')->click('Next')->seePageIs('/beta');}
}復制代碼

注意到,在我們新建的 testClickNextForBeta() 方法中,我們并沒有檢查每一個頁面的內容。 其他測試都成功的檢查了兩個頁面的內容,所以這里我們只關心點擊 「Next」鏈接將發送到?/beta

你現在可以運行測試組件了,但就像預料的一樣測試將不通過,因為我們還沒有更新我們的 HTML。

接下來,我們將更新?BetaTest?來做類似的事情:

<?php
class BetaTest extends TestCase
{public function testDisplaysBeta(){$this->visit('/beta')->see('Beta')->dontSee('Alpha');}public function testClickNextForAlpha(){$this->visit('/beta')->click('Previous')->seePageIs('/alpha');}
}復制代碼

接下來,我們更新我們的 HTML 模版。

./resources/views/alpha.blade.php

<!DOCTYPE html>
<html><head><title>Alpha</title></head><body><p>This is the Alpha page.</p><p><a href="/beta">Next</a></p></body>
</html>復制代碼

./resources/views/beta.blade.php

<!DOCTYPE html>
<html><head><title>Beta</title></head><body><p>This is the Beta page.</p><p><a href="/alpha">Previous</a></p></body>
</html>復制代碼

保存文件,再一次執行 PHPUnit:

> ./vendor/bin/phpunit
PHPUnit 4.8.19 by Sebastian Bergmann and contributors.F....F..Time: 175 ms, Memory: 14.00MbThere were 2 failures:1) AlphaTest::testDisplaysAlpha
Failed asserting that '<!DOCTYPE html>
<html><head><title>Alpha</title></head><body><p>This is the Alpha page.</p><p><a href="/beta">Next</a></p></body>
</html>
' does not match PCRE pattern "/Beta/i".2) BetaTest::testDisplaysBeta
Failed asserting that '<!DOCTYPE html>
<html><head><title>Beta</title></head><body><p>This is the Beta page.</p><p><a href="/alpha">Previous</a></p></body>
</html>
' does not match PCRE pattern "/Alpha/i".FAILURES!
Tests: 8, Assertions: 23, Failures: 2.復制代碼

然而測試失敗了。如果你仔細觀察我們的新 HTML,你將注意到我們分別有術語?beta?和?alpha?在?/alpha?和?/beta?頁面。這意味著我們需要稍微更改我們的測試讓它們與誤報不匹配。

在每一個?AlphaTest?和?BetaTest?類,更新?testDisplays* 方法去使用?dontSee('<page> page')。通過這種方式,這將僅僅匹配字符串而不是那個術語。

兩個測試文件如下所示:

./tests/AlphaTest.php

<?php
class AlphaTest extends TestCase
{public function testDisplaysAlpha(){$this->visit('/alpha')->see('Alpha')->dontSee('Beta page');}public function testClickNextForBeta(){$this->visit('/alpha')->click('Next')->seePageIs('/beta');}
}復制代碼

./tests/BetaTest.php

<?php
class BetaTest extends TestCase
{public function testDisplaysBeta(){$this->visit('/beta')->see('Beta')->dontSee('Alpha page');}public function testClickNextForAlpha(){$this->visit('/beta')->click('Previous')->seePageIs('/alpha');}
}復制代碼

再一次運行你的測試,所有的測試都應該通過了。我們現在已經測試我們所有的新文件,包括頁面中的 Next/Previous 鏈接。

通過 Semaphore 對 PHPUnit 持續集成

通過 Semaphore設置?持續集成你可以自動執行你的測試。

這樣每一次你進行?git push?提交代碼的時候都會執行你的測試,并且 Semaphore 預裝了所有最新的 PHP 版本。

如果你還沒有一個 Semaphore 賬戶, 先去 注冊一個免費的 Semaphore 賬戶?。接下來需要做的是將它?添加到你的項目,并按照提示逐步去做來執行你的測試:

composer install --prefer-source
phpunit復制代碼

關于?PHP 持續集成 的更多信息,請參照 Semaphore 文檔。

結語

你應該注意到本教程中的所有測試都有一個共同的主題:它們都非常簡單。 這是學習如何使用基本的測試斷言和輔助函數,并且盡可能的使用它們的好處之一。編寫測試越簡單,測試就越容易理解和維護。

掌握了本教程中介紹的 PHPUnit 斷言之后,你還可以去 PHPUnit 文檔 找到更多內容。 所有的斷言都遵循基本的模式,但你會發現,在大多數測試中都會返回基本的斷言。

對于 PHPUnit 斷言來說,Laravel 的測試輔助函數是極好的補充,這讓應用程序的測試變的非常容易。也就是說,重要的是要認識到,對于我們寫測試,我們只檢查關鍵信息,而不是整個頁面。這使得測試變得簡單,并允許頁面內容隨著應用程序的變化而變化。如果關鍵信息仍然存在,測試仍然通過,每個人都會滿意。

文章轉自: https://learnku.com/laravel/t/24559
更多文章:https://learnku.com/laravel/c/translations

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275712.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275712.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275712.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Brad Wilson寫的 ASP.NET MVC 3 Service Location 系列文章索引

Brad Wilson在他自己的博客寫了有關ASP.NET MVC3依賴注入支持的一系列文章&#xff0c;但由于某些原因&#xff08;你懂的&#xff09;&#xff0c;需要FQ才能閱讀。 為了方便自己也方便喜歡的同學&#xff0c;特意FQ再拷貝回來發布&#xff0c;以下是這一系列文章的索引&#…

注釋標記的原則_它關系到平臺如何標記操縱的媒體。 這是設計師應遵循的12條原則。

注釋標記的原則By Emily Saltz, Tommy Shane, Victoria Kwan, Claire Leibowicz, Claire Wardle埃米莉薩爾茨 ( Emily Saltz) &#xff0c; 湯米沙恩 ( Tommy Shane) &#xff0c; 關 穎琳 ( Victoria Kwan) &#xff0c; 克萊爾萊博維奇 ( Claire Leibowicz) &#xff0c; 克萊…

saltapi java_搭建基于Jenkins salt-api的運維工具

1. 安裝salt-master和salt-minion安裝過程不再贅述&#xff0c;請參考http://docs.saltstack.com/en/latest/topics/installation/index.html2. 安裝salt-api&#xff0c;cherrypy用來jenkins與salt通信啟用salt-api在salt master的配置文件中添加rest_cherrypy:port: 8010host…

他開發了redux,昨晚字節一面卻掛了?

大家好&#xff0c;我是若川&#xff0c;誠邀你進群交流學習。今天分享一次直播的記錄。我寫過redux源碼文章。動手按照文中例子學習&#xff0c;我相信會有所收獲。學習源碼系列、面試、年度總結、JS基礎系列redux的作者是誰&#xff1f;Dan&#xff0c;他的全稱叫做Dan Abram…

Onew積極開拓國際市場,為全球用戶提供全方位金融服務

當區塊鏈技術剛被提出的時候&#xff0c;金融被認為是最主要的應用場景之一&#xff0c;具體包括建立基于區塊鏈技術的銀行間點對點支付結算系統和跨境支付系統、在交易所運用區塊鏈技術實現股權的登記和轉讓等。 區塊鏈應用于金融領域有著天生的絕對優勢&#xff0c;主觀來看&…

高通董事長:努力降低智能手機價格

高通董事長&#xff1a;努力降低智能手機價格 高通公司董事長兼CEO保羅雅各布近日表示&#xff0c;2011年高通除了繼續與各方合作提供高端及各層次智能手機外&#xff0c;將更加致力于降低智能手機的價格。 手機將成為個人生活中心 作為移動通信芯片領域的霸主&#xff0c;高通…

mysql數據庫的新特性_【數據庫】MySQL新特性歸檔介紹

MySQL 8.0.17發布了&#xff0c;看了下release note&#xff0c;發現果真如之前預期的那樣&#xff0c;恢復了redo log歸檔(redo log archiving)功能。之所以說是“恢復”&#xff0c;那是因為在InnoDB非常古老的版本(MySQL 4.0.6之前的版本)才存在&#xff0c;之后就取消了&am…

為什么同事寫的代碼那么優雅~

大家好&#xff0c;我是若川&#xff0c;誠邀你進群交流學習。今天分享一篇相對輕松的代碼簡潔之道。學習源碼系列、面試、年度總結、JS基礎系列內容出自《代碼整潔之道》、Alex Kondov[1]的博文tao-of-react[2]和《Clean Code of Javascript》image.png代碼整潔有什么用&#…

[轉]讓你賺大錢成富翁的4個投資習慣

本文轉自&#xff1a;http://bbs.jrj.com.cn/msg,68723793.html 第一條&#xff1a;對自己進行投資  這是最大最大的投資&#xff0c;當然收獲也是最為豐盛的。藝不壓身&#xff0c;這句話非常有哲理。朋友今年27歲&#xff0c;可是毫不夸張地說&#xff0c;他已經具有了百萬…

thymeleaf th:href url傳遞多參數

<a th:href"{/teacherShowMember(class_id${class.classId}&#xff0c;class_name${class.className})}"></a> thymeleaf使用&#xff08;,,&#xff09;的形式解析多個參數,結合${}放置變量十分方便 傳統URL傳遞多參數使用&#xff1f;&拼接 <a…

spring 加載java類_在Spring中基于Java類進行配置的完整步驟

在Spring中基于Java類進行配置的完整步驟發布于 2020-7-7|復制鏈接基于Java配置選項&#xff0c;可以編寫大多數的Spring不用配置XML&#xff0c;下面前言JavaConfig 原來是 Spring 的一個子項目&#xff0c;它通過 Java 類的方式提供 Bean 的定義信息&#xff0c;在 Spring4 的…

2021 年最值得了解的 Node.js 工具(下)

大家好&#xff0c;我是若川&#xff0c;誠邀你加群長期交流。今天分享一篇用得上的 node 庫。下篇。鏈接地址&#xff1a;https://github.com/huaize2020/awesome-nodejs。上篇是&#xff1a;2021 年最值得了解的 Node.js 工具?前言&#xff1a;前端時間分享了這些node開源工…

技術點

前端所用技術 后臺頁面 感謝 H-ui、FlatLab 提供靜態頁面支持Ztree&#xff1a;jQuery樹插件DataTables&#xff1a;jQuery表格插件Layer&#xff1a;web彈層組件Distpicker&#xff1a;中國省市區地址三級聯動插件KindEditor&#xff1a;富文本編輯器 簡潔方便 沒UEditor那么多…

掃描java類文件_java遞歸與非遞歸實現掃描文件夾下文件的實例代碼

java遞歸與非遞歸實現掃描文件夾下所有文件java掃描指定文件夾下面的所有文件&#xff0c;供大家參考&#xff0c;具體內容如下掃描一個文件夾下面的所有文件&#xff0c;因為文件夾的層數沒有限制可能多達幾十層幾百層&#xff0c;通常會采用兩種方式來遍歷指定文件夾下面的所…

【阿里內部應用】基于Blink為新商業調控打造實時大數據交互查詢服務

基于Blink為新商業調控打造實時大數據交互查詢服務 案例與解決方案匯總頁&#xff1a;阿里云實時計算產品案例&解決方案匯總從IT到DT、從電商到新商業&#xff0c;阿里巴巴的每個細胞都存在大數據的DNA&#xff0c;如何挖掘大數據的價值成為搶占未來先機的金鑰匙&#xff0…

Vite 的好與壞

大家好&#xff0c;我是若川&#xff0c;誠邀你進群交流學習。今天分享一篇關于Vite的文章。學習源碼系列、面試、年度總結、JS基礎系列。全文 3000 字&#xff0c;歡迎點贊關注轉發一、Vite 是什么2020年4月&#xff0c;尤大大發了這么一個推&#xff1a;隨后&#xff0c;2021…

Windows phone 7新開發工具發布

春節假期已經接近尾聲. 馬上第一個工作日就要來臨. 春節真的不再是一個簡簡單單的節日. 有時讓人感到欣喜 這意味這一年的忙碌都會因為這個節日的到來而畫上一個終止符.面臨一個不長也不短的假期.眼下的一年翻過去 新的一年即將到來. 似乎一切都可以重新開始. 有時又令人感到無…

opentaps mysql_opentaps 1.4 聯接 mysql 筆記

opentaps 1.4 連接 mysql 筆記一、安裝 MySQ 略...二、創建MySQL Database opentaps ERP CRM1.mysql -u root -h 127.0.0.1 -p 2.mysql>create database opentaps default CHARACTER SET utf8 COLLATE utf8_general_ci;3.mysql>create user opentaps;4.mysql>grant …

這10道springboot常見面試題你需要了解下

1、什么是Spring Boot&#xff1f;多年來&#xff0c;隨著新功能的增加&#xff0c;spring變得越來越復雜。只需訪問https://spring.io/projects頁面&#xff0c;我們就會看到可以在我們的應用程序中使用的所有Spring項目的不同功能。如果必須啟動一個新的Spring項目&#xff0…

Silverlight中使用MIRIA進行觸屏編程

Silverlight for Windows phone7中可以使用XNA提供的功能進行觸屏編程&#xff0c;不過暫時還沒有網頁Silverlight的XNA移植。經過搜索發現MIRIA這個開源項目http://miria.codeplex.com/ 可以在Silverlight中實現Touch、Gesture的功能。 用法如下&#xff1a; 1、項目中引用MIG…