qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Apache安裝配置管理

           一、安裝Apache
            下載地址:http://httpd.apache.org/
            1. 安裝Apache
            # tar  zxvf  httpd-2.2.11.tar.gz
            # cd  httpd-2.2.11
            # ./configure  --prefix=/usr/local/apache  --enable-so
            //編譯時加上加載模塊參數--enable-so
            # make
            # make  install
            2. 配置系統啟動時自動啟動Apache服務。
            # vi  /etc/rc.d/rc.local
            //在rc.local上加入一行/usr/local/apache/bin/apachectl –k  start。
            二、配置Apache
            1. 修改httpd.conf文件
            # vi  /usr/local/apache/conf/httpd.conf
            1) 設置根目錄的路徑
            根目錄是指Apache存放配置文件和日志文件的目錄,配置參數為ServerRoot,默認位于“/usr/local/apache”。命令如下:
            2) 設置監聽IP地址及端口號
            默認偵聽本機所有IP地址的TCP80端口,命令如下:
            Listen 80
            用戶也可以按自己的需求,使用多個Listen語句在多個地址和端口上偵聽客戶端請求。比如:
            Listen 192.168.99.9:80
            Listen 172.16.0.20:8080
            3) 設置系統管理員E-mail
            使用ServerAdmin參數設置管理員E-mail,比如管理員的Email地址為root@guoxuemin.cn
            4) 設置服務器主機的名稱
            參數ServerName用來設置服務器的主機名稱,如果沒有域名則填入服務器的IP地址,比如服務器的IP地址為192.168.99.9:
            5) 設置主目錄的路徑
            用戶可以使用參數DocumentRoot配置服務器主目錄默認路徑,比如,主目錄路徑為:/usr/local/apache2/htdocs
            6) 設置默認文件
            Apache的默認文件名為index.html,可以使用Directory Index參數來配置,比如,將index.php設置為默認文件名:index.php index.html
            7)測試
            打開瀏覽器,輸入地址:http://192.168.99.9,可以打開站點了:
            2. 配置目錄權限
            使用<Directory 目錄路徑>和</Directory>設置目錄的權限。比如:
            <Directory  “/var/www/icons”>
            Options  Indexes  MultiViews
            AllowOverride  None
            Order  allow,deny
            Allow  from  all
            </Directory>
          說明:
            1)定義目錄特性選項Options
            可選參數:
            Indexes:該特性表明目錄允許“目錄瀏覽”;
            MultiViews:該特性表明目錄允許內容協商的多重試圖;
            All:包含了除MultiViews外的所有特性;
            ExecCGI:該特性表明允許在該目錄下執行CGI腳本;
            FollowSymLinks:該特性表明允許在該目錄下使用符號連接。
            2).htaccess文件
            可以通過.htaccess文件(訪問控制文件)設置目錄的權限。
            AccessFileName  .htaccess
            配置參數AllowOverride指定目錄的.htaccess文件中指令的類型,包括All、None與Options、FileInfo、AuthConfig、Limit的任意組合。一般將AllowOverride設置為“None”,禁止使用.htaccess文件,當AllowOverride參數為All時,.htaccess文件可以覆蓋任何以前的配置。
            3)設置訪問控制
            使用Order選項來定義訪問權限。
            比如以下語句表明允許所有客戶機的訪問:
            Order  allow,deny
            Allow  from  all
            以下語句表明只允許網段192.168.99.0/24的客戶機訪問,但IP地址為192.168.99.254這個客戶機除外:
            Order  allow,deny
            Allow from  192.168.99.0/24
            Deny from  192.168.99.254
            用戶可以根據需要,按上述方法配置自己的目錄權限。
            3. 創建虛擬目錄
            使用Alias選項創建虛擬目錄,比如,建立“/icons/”這個虛擬目錄,其對應的物理路徑為“/var/www/icons/”:
            Alias  /icons/  “/var/www/icons/”
            4. 用戶認證
            比如,有一個名為myweb的虛擬目錄,其對應的物理路徑是“/usr/local/myweb”,現對其啟用用戶認證功能,只允許用戶Tonyguo和Wayne訪問。
            1)建立虛擬目錄并設置用戶認證:
            Alias /myweb/ “/usr/local/myweb/”
            <Directory  “/usr/local/myweb/”>
            Options  none
            AllowOverride  None
            Order  allow,deny
            Allow  from  all
            AuthType Basic
            AuthName “Please Login: ”
            AuthUserFile/usr/local/apache/bin/mywebpwd
            Require User Tongguo wayne
            </Directory>
            2) 建立口令文件并為用戶設置口令
            /usr/local/apache/bin/htpasswd –c /usr/local/apache/bin/mywebpwd Tonyguo
            -c選項表示無論口令文件是否已經存在,都會重新寫入文件并刪除原內容。所以第二個用戶wayne不需要使用-c選項
            3)測試
            在瀏覽器中輸入:http://192.168.99.9/myweb,可以看到如下對話框:
            輸入用戶名和密碼后就可以訪問網站了:
            三、配置虛擬主機
            1. 配置基于IP的虛擬主機
            1)IP地址相同,但端口號不同的虛擬主機配置
            比如使用192.168.99.9的兩個不同端口80和8080發布兩個不同站點, 虛擬主機分別對應的目錄為/usr/local/apache/htdocs/web1和/usr/local/apache/htdocs/web2:
          Listen 80
          Listen 8080
          <VirtualHost  192.168.99.9:80>
          ServerSignature  email
          DocumentRoot  /usr/local/apache/htdocs/web1
          DirectoryIndex  index.html  index.htm
          LogLevel  warm
          HostNameLookups  off
          </VirtualHost>
          <VirtualHost  192.168.99.9:8080>
          ServerSignature  email
          DocumentRoot  /usr/local/apache/htdocs/web2
          DirectoryIndex  index.html  index.htm
          LogLevel  warm
          HostNameLookups  off
          </VirtualHost>
           2)端口相同,ip不同的虛擬主機配置
            比如服務器有兩個IP地址192.168.99.9和192.168.99.10,使用這兩個IP創建兩臺虛擬主機,虛擬主機分別對應的目錄為/usr/local/apache/htdocs/web1和/usr/local/apache/htdocs/web2。設置方法如下:
          <VirtualHost  192.168.99.9>
          ServerName  192.168.99.9:80
          DocumentRoot  /usr/local/apache/htdocs/web1
          DirectoryIndex  index.html  index.htm
          </VirtualHost>
          <VirtualHost  192.168.99.10>
          ServerName  192.168.99.10:80
          DocumentRoot  /usr/local/apache/htdocs/web2
          DirectoryIndex  index.html  index.htm
          </VirtualHost>
            2. 配置基于域名的虛擬主機
            比如有兩個域名guoxuemin.cn和tonyguo.com需要使用同一臺服務器192.168.99.9,那么可以這樣配置:
          NameVirtualHost  192.168.99.9
          <VirtualHost  www.guoxuemin.cn>
          ServerName  www.guoxuemin.cn:80
          ServerAdmin  admin@guoxuemin.cn
          DocumentRoot  /usr/local/apache/htdocs/web1
          DirectoryIndex  index.html  index.htm
          ErrorLog  logs/web1/error_log
          Customlog  logs/web1/access_log  combined
          </VirtualHost>
          <VirtualHost  www.tonyguo.com>
          ServerName   www.tonyguo.com:80
          ServerAdmin  admin@tonyguo.com
          DocumentRoot  /usr/local/apache/htdocs/web2
          DirectoryIndex  index.html  index.htm
          ErrorLog  logs/web1/error_log
          Customlog  logs/web1/access_log  combined
          </VirtualHost>
          <VirtualHost *:8088>
          serverAdmin new@student.com
          DocumentRoot "/web/web1"
          <Directory /web/web1>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
          <VirtualHost *:8089>
          serverAdmin new@student.com
          DocumentRoot "/web/web2"
          <Directory /web/web2>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
          <VirtualHost 192.168.88.144:80>
          serverAdmin new@student.com
          DocumentRoot "/web/web3"
          <Directory /web/web3>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
          <VirtualHost 192.168.88.145:80>
          serverAdmin new@student.com
          DocumentRoot "/web/web4"
          <Directory /web/web4>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
          <VirtualHost ftp.com>
          ServerName ftp.com:80
          DocumentRoot /web/ftp
          <Directory /web/ftp>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
          <VirtualHost mail.com>
          ServerName mail.com:80
          DocumentRoot /web/mail
          <Directory /web/mail>
          Options FollowSymlinks
          AllowOverride None
          Order Allow,Deny
          Allow from all
          </Directory>
          DirectoryIndex index.html index.php index.htm
          </VirtualHost>
            負載均衡
            #訪問test目錄時負載均衡
            在modules目錄下:導入mod
          /usr/local/apache2/bin/apxs -c -i mod_proxy.c proxy_util.c
          /usr/local/apache2/bin/apxs -c -i mod_proxy_balancer.c
          /usr/local/apache2/bin/apxs -c -i  mod_proxy_http.c
          vi http.conf
          LoadModule proxy_module            modules/mod_proxy.so
          LoadModule proxy_balancer_module   modules/mod_proxy_balancer.so
          LoadModule proxy_http_module       modules/mod_proxy_http.so
          ProxyRequests Off
          <Proxy balancer://clusterphpinfo>
          BalancerMember http://192.168.88.134:8089  loadfactor=5
          BalancerMember http://192.168.88.134:8088  loadfactor=1
          #weight
          ProxySet lbmethod=bytraffic
          </Proxy>
          ProxyPass /test balancer://clusterphpinfo stickysession=STICK_PORT_TOKEN nofailover=On
          ProxyPassReverse /test balancer://clusterphpinfo
          <Location /balancer-manager>
          SetHandler balancer-manager
          Order Deny,Allow
          Allow from all
          #Allow from 192.168.88.*
          </Location>

          posted @ 2014-08-12 09:31 順其自然EVO 閱讀(320) | 評論 (0)編輯 收藏

          Appium探索—Mac OS Python版

          Appium官網所描述的特性,都很吸引人,剛好最近在研究Mobile Automation Testing,所以很有興趣探索下Appium這個年輕的工具。
            不過看了官網的documents,實在是讓初入門的我感覺摸不著頭腦。
            所以,我只能search網上有限的資源,先從運行Appium提供的支持Python,Javascript,Java,Ruby等語言的examples開始慢慢體會Appium的工作原理。
            在此,記錄這個探索的過程。
            首先嘗試成功的是,在Mac OS上的Python example。
            這里,Appium的使用,主要有四個方面的因素:
            一,Appium Server
            1. Appium Server的安裝
            前提:已經安裝node.js&npm
            安裝:在mac上打開shell
            #sudo npm install -g appium  //加上sudo以防Permission的問題
            #npm install wd  //這個還不清楚有什么影響??
            ------------
            正常情況下,這樣,Appium Server就安裝成功了。
            啟動:
            #appium &    //若顯示如下信息,說明Appium Server啟動成功?。ú患?amp;,也可以啟動~~~)
            二,Selenium WebDriver
            因為是Python版,所以就去Selenium官網下載Python的WebDriver(selenium-2.39.0.tar.gz)
            https://pypi.python.org/pypi/selenium
            解壓:
            #gzip -dc selenium-2.39.0.tar.gz | tar xvf -
            安裝:
            #cd selenium-2.39.0
            #sudo python setup.py install  //sudo依舊是解決Permission的問題
           ?。?/div>
            這樣,WebDriver就安裝成功了。
            三,要測試的app
            測試的是appium提供的TestApp
            首先,我們需要用xcode編譯這個app
            #cd appium
            #cd sample-code/apps/TestApp
            #xcodebuild -sdk iphonesimulator  //為了防止iphonesimulator和設置的沖突,沒有注明iphonesimulator的版本
           ?。?/div>
            如果看到** BUILD SUCCEEDED **,這個TestApp就build成功了。
           四,Automation Scripts
            自動化腳本,也是用appium提供的,在appium目錄下可以找到
            #cd appium
            #cd sample-code
            #cd examples/python
            #python simple.py      //執行測試腳本

          老外寫的一個測試用例

           Test case example:
            Test Case ID: CUST.01
            Function: Add a new Customer
            Data Assumptions: Customer database has been restored
            General Description:
            Add a new customer, via the Customer Add screen, and validate that new Customer was displayed corrected on the All Customer Screen.
            Benefits:
            1. Easier to automated - all have same structure
            2. Data requirements are clearly defined
            3. Navigation is precise
            4. Expected results for each action is specific - no guess work involved

          posted @ 2014-08-12 09:28 順其自然EVO 閱讀(212) | 評論 (0)編輯 收藏

          性能測試策略整理

            1、基準測試
            在系統無壓力下,單用戶迭代執行連續時間或次數,取得事物平均相應時間,作為分析衡量的標準。
            目地在于---->衡量性能測試環境是否異常
            ---->驗證腳本和參數的正確性
            ---->獲取系統處理事物的性能數據
            2.并發測試
            檢測系統多并發情況下,服務器硬件資源的利用情況、網絡使用情況、應用服務器情況等。
            同時也可以檢查系統服務器是否健壯(是否會出現原本邏輯正確的事物,在并放情況下出現了邏輯錯誤。)
            3、混合測試
            混合場景測試,對典型腳本按照一定比例組成的混合腳本(最接近生產環境),找出系統可能存在的瓶頸
            4、浪涌測試
            高強度和低負載的交叉壓力測試,驗證系統在兩種情況下的穩定性,以找出在增加和減少負載的過程中由于突然的占用和釋放系統資源而引起的問題
            5、容量測試
            測出系統的最大容量。通過不斷調整負載,找出系統在滿足性能指標的條件下的最優容量,此配置下系統的最大并發數
            6、穩定性測試
            模擬一定數量用戶長時間運行,驗證系統在長時間運行后用戶對系統的訪問操作成功率是否降低,以找出系統潛在的內存泄漏等問題。
            7、疲勞測試
            就是對已飽和的系統測試。采用滿足性能指標的條件下的最大用戶數持續執行一段時間業務,通過綜合分析業務執行指標和資源監控指標來確定系統處理的最大工作量的性能指標
            8、擴展測試
            已知性能瓶頸的前提下提高系統容量、或提升硬件等,找出性能瓶頸
            9、批處理測試
            處理大量數據,測試程序處理效率(在規定的時間內完成接收來自上游系統的數據和傳遞數據給下游系統)和服務器資源情況

          posted @ 2014-08-11 14:58 順其自然EVO 閱讀(196) | 評論 (0)編輯 收藏

          Php常用代碼數據庫的連接及讀取和寫入

           數據庫連接代碼(php+Mysql)以及讀取表中內容:
            例如:php連接MySql
            1.為了更好地設置數據連接,一般會將數據連接所涉及的值定義成變量.
            $mysql_server_name='localhost'; //改成自己的mysql數據庫服務器
            $mysql_username='root'; //改成自己的mysql數據庫用戶名
            $mysql_password='123456'; //改成自己的mysql數據庫密碼
            $mysql_database='Mydb'; //改成自己的mysql數據庫名
            也可把以上變量放在一個文件里,可以隨時讓其他文件調用.
            例如: 將以上內容放在:db_config.php 那么在其他需要用到數據庫的頁面直接調用.
            調用代碼:require("db_config.php");
            2.連接數據庫
            $conn=mysql_connect($mysql_server_name,$mysql_username,$mysql_password) or die("error connecting") ; //連接數據庫
            mysql_query("set names 'utf8'"); //數據庫輸出編碼 應該與你的數據庫編碼保持一致.南昌網站建設公司百恒網絡PHP工程師建議用UTF-8 國際標準編碼.
            mysql_select_db($mysql_database); //打開數據庫
            $sql ="select * from news "; //SQL語句
            $result = mysql_query($sql,$conn); //查詢
            3.讀取表中的內容,這里我們用while,可以根據具體情況,用for 或其他的.
            while($row = mysql_fetch_array($result))
            {
            echo "<div style=\"height:24px; line-height:24px; font-weight:bold;\">"; //排版代碼
            echo $row['Topic'] . "<br/>";
            echo "</div>"; //排版代碼
            }
            4.php寫入數據庫,Mysql數據的寫入
            $conn=mysql_connect($mysql_server_name,$mysql_username,$mysql_password); //連接數據庫
            mysql_query("set names 'utf8'"); //數據庫輸出編碼
            mysql_select_db($mysql_database); //打開數據庫
            $sql = "insert into messageboard (Topic,Content,Enabled,Date) values ('$Topic','$Content','1','2011-01-12')";
            mysql_query($sql);
            mysql_close(); //關閉MySQL連接

          posted @ 2014-08-11 14:57 順其自然EVO 閱讀(296) | 評論 (0)編輯 收藏

          當ASP.NET Forms驗證方式遭遇蘋果IOS

          一、問題出現
            我在用ASP.NET MVC4做微信開發的時候,用Forms驗證方式做為authentication。
            一般都是在web.config加:
            <authentication mode="Forms" >
            <forms loginUrl="~/Account/Login" name="webcookies"  slidingExpiration="true" timeout="30" />
            </authentication>
            然后用戶登錄成功后就設置Cookies,代碼如下:
          public static void SetTicket(HttpResponseBase response, bool remeberMe, int version, string identity, string displayName)
          {
          FormsAuthentication.SetAuthCookie(identity, remeberMe);
          string userData = displayName;
          var authTicket = new FormsAuthenticationTicket(
          version,
          identity,
          DateTime.Now,
          DateTime.Now.AddDays(remeberMe ? 30 : 1),
          remeberMe,
          userData);
          string encrytedTicket = FormsAuthentication.Encrypt(authTicket);
          HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,
          encrytedTicket);
          response.Cookies.Add(authCookie);
          }
            我這里用FormsAuthenticationTicket.Version存儲用戶角色ID。
            一開始還為自己的機智和精巧的設計洋洋得意,而且在安卓手機上運行完全沒有問題。但是在IOS上,不管我Version設置成什么值,它的值始終都是2。
            根據msdn的解釋:如果 FormsAuthenticationTicket 是使用不提供 version 參數的構造函數創建的,則 Version 屬性返回 2;否則,Version 屬性返回提供給FormsAuthenticationTicket 構造函數的值。
            地址:http://technet.microsoft.com/zh-cn/magazine/system.web.security.formsauthenticationticket.version(VS.110).aspx
            我明明已經使用了提供 version 參數的構造函數創建的,但是在IOS上就是不好使。
            找了很多資料都沒有得到一個很好的解釋,希望博客園的園們能幫我解釋一下這個問題呀。
            后來看到微軟的那個頁面最下面:支持的平臺:
            Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(不支持服務器核心角色), Windows Server 2008 R2(支持帶 SP1 或更高版本的服務器核心角色;不支持 Itanium)
            我也就釋懷了。
            不管怎么著,困擾我許久的問題終于找到問題所在了,謹以此文告誡后來者。

          posted @ 2014-08-11 14:57 順其自然EVO 閱讀(394) | 評論 (3)編輯 收藏

          我用JAVA做了個簡易圖像相似度計算器

           筆主利用這個七夕前后兩天的寂寞時光,用JAVA磨了一個簡單的圖像相似度計算小程序,就在剛才終于糾結完畢,輸出了1.0版本,小小的滿足了一下可憐的虛榮心..
            UI設計圖:
            實際運行效果圖:
          關鍵算法:
          1 // 全流程
          2 public static void main(String[] args) throws IOException {
          3     // 獲取圖像
          4     File imageFile = new File("c:/1.jpg");
          5     Image image = ImageIO.read(imageFile);
          6     // 轉換至灰度
          7     image = toGrayscale(image);
          8     // 縮小成32x32的縮略圖
          9     image = scale(image);
          10     // 獲取灰度像素數組
          11     int[] pixels = getPixels(image);
          12     // 獲取平均灰度顏色
          13     int averageColor = getAverageOfPixelArray(pixels);
          14     // 獲取灰度像素的比較數組(即圖像指紋序列)
          15     pixels = getPixelDeviateWeightsArray(pixels, averageColor);
          16     // 獲取兩個圖的漢明距離(假設另一個圖也已經按上面步驟得到灰度比較數組)
          17     int hammingDistance = getHammingDistance(pixels, pixels);
          18     // 通過漢明距離計算相似度,取值范圍 [0.0, 1.0]
          19     double similarity = calSimilarity(hammingDistance);
          20 }
          21
          22 // 將任意Image類型圖像轉換為BufferedImage類型,方便后續操作
          23 public static BufferedImage convertToBufferedFrom(Image srcImage) {
          24     BufferedImage bufferedImage = new BufferedImage(srcImage.getWidth(null),
          25             srcImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
          26     Graphics2D g = bufferedImage.createGraphics();
          27     g.drawImage(srcImage, null, null);
          28     g.dispose();
          29     return bufferedImage;
          30 }
          31
          32 // 轉換至灰度圖
          33 public static BufferedImage toGrayscale(Image image) {
          34     BufferedImage sourceBuffered = convertToBufferedFrom(image);
          35     ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
          36     ColorConvertOp op = new ColorConvertOp(cs, null);
          37     BufferedImage grayBuffered = op.filter(sourceBuffered, null);
          38     return grayBuffered;
          39 }
          40
          41 // 縮放至32x32像素縮略圖
          42 public static Image scale(Image image) {
          43     image = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH);
          44     return image;
          45 }
          46
          47 // 獲取像素數組
          48 public static int[] getPixels(Image image) {
          49     int width = image.getWidth(null);
          50     int height = image.getHeight(null);
          51     int[] pixels = convertToBufferedFrom(image).getRGB(0, 0, width, height,
          52             null, 0, width);
          53     return pixels;
          54 }
          55
          56 // 獲取灰度圖的平均像素顏色值
          57 public static int getAverageOfPixelArray(int[] pixels) {
          58     Color color;
          59     long sumRed = 0;
          60     for (int i = 0; i < pixels.length; i++) {
          61         color = new Color(pixels[i], true);
          62         sumRed += color.getRed();
          63     }
          64     int averageRed = (int) (sumRed / pixels.length);
          65     return averageRed;
          66 }
          67
          68 // 獲取灰度圖的像素比較數組(平均值的離差)
          69 public static int[] getPixelDeviateWeightsArray(int[] pixels,final int averageColor) {
          70     Color color;
          71     int[] dest = new int[pixels.length];
          72     for (int i = 0; i < pixels.length; i++) {
          73         color = new Color(pixels[i], true);
          74         dest[i] = color.getRed() - averageColor > 0 ? 1 : 0;
          75     }
          76     return dest;
          77 }
          78
          79 // 獲取兩個縮略圖的平均像素比較數組的漢明距離(距離越大差異越大)
          80 public static int getHammingDistance(int[] a, int[] b) {
          81     int sum = 0;
          82     for (int i = 0; i < a.length; i++) {
          83         sum += a[i] == b[i] ? 0 : 1;
          84     }
          85     return sum;
          86 }
          87
          88 // 通過漢明距離計算相似度
          89 public static double calSimilarity(int hammingDistance){
          90     int length = 32*32;
          91     double similarity = (length - hammingDistance) / (double) length;
          92
          93     // 使用指數曲線調整相似度結果
          94     similarity = java.lang.Math.pow(similarity, 2);
          95     return similarity;
          96 }
            UI部分的代碼就不公開了,成品下載地址如下(使用JDK1.5):
            http://download.csdn.net/detail/u011088871/7711833
            解壓后打開 run.bat 批處理文件就可以跑起來了 :)

          posted @ 2014-08-11 09:59 順其自然EVO 閱讀(278) | 評論 (0)編輯 收藏

          需求變更管理綜述

           需求變更是軟件項目一個突出的特點,也是軟件項目最為普遍的一個特點。雖然這與人類認識問題的自然規律是一致的,但是頻繁而無管理的需求變更非常容易導致復雜、無形的軟件在多變的情況下失控,加劇了軟件開發過程中的不穩定性,從而造成多方的損失。那么如何對需求變更加以有效的控制和管理,從而保證軟件開發的進度、成本和質量,便成為軟件開發過程中一個值得思考的問題。
            下面,我們將“需求變更管理”作為一個“項目”,按照問題定義、需求分析、設計、開發等步驟,從軟件工程的角度來加以分析,而這樣的討論過程也正符合了我們的開發流程,相信大家會對需求變更管理的認識更加深刻。
            問題定義
            根據軟件工程思想,需求說明書一般要經過需求評審的過程。在需求說明書經過論
            證后,需要在原有基礎上補充新的需求或對其進行修改和刪減,則均屬于需求變更。
            這是軟件開發過程中不可避免的問題,如何有效應對和處理需求變更,已經成為一個廣泛受到關注的話題。
            需求分析及評價
            由于頻繁需求變更且同時缺乏有效控制流程而導致軟件項目失敗的案例不勝枚舉,
            面臨這種不穩定性,如果開發團隊缺少明確的需求變更管理控制或者采用的控制機制無效,很可能出現成本增高、人力緊缺、項目拖延甚至是失敗,這也就有了進行需求變更管理的需求。
            誠然,需求變更管理不可能根本解決問題,但是實施嚴格的軟件需求變更管理能最大限度地控制需求變更帶來的負面影響,從而保證項目的可控性和穩定性,這也正是進行需求變更管理的目的所在。
            設計
            這里的設計指的就是如何來制定需求變更管理的執行計劃。主要分以下幾個階段:
            獲取需求基線:需求的基線是指是否容許需求變更的分界線。需求分析人員在充分與客戶用戶進行溝通的基礎上形成第一個版本的需求文檔,這個需求文檔在通過需求評審后即可以建立第一個需求基線。此后每次需求變更并經過需求評審后,都要重新確定新的需求基線。變更控制委員會為有效進行需求變更控制,必然要做的工作就是保存好各個版本的需求基線,維護需求基線文檔,以備不時之需。隨著項目的進展,基線將越定越高,即容許的需求變更將越來越少。
            分析變更影響:對于提交的每項需求變更請求,應確定它對項目整體進度的影響和對其他相關開發任務的影響,并且一定要明確完成這些變更相關任務的工作量。只有經過全面的分析,變更控制委員會才能夠做出更好的決策。進行變更影響分析可以對申請的需求變更有更深刻的理解,通過對變更內容的更深刻的理解,才能做出對正在進行的工作的調整的部署。
            維護變更記錄:記錄每個需求變更文檔的版本號、日期、所做的變更、原因等,當然應該明確該文檔由誰來負責更新。
            衡量需求穩定性:變更控制委員會需要對需求變更的整體有良好的把握,通過記錄需求基準的數量可以獲得宏觀需求的變更次數;同時還應該記錄一段時間內(如每周、每月)的變更數量,最好按變更的類別來列出詳細信息。如果某一需求過于頻繁變更,則說明對該問題的認識還不深入或者說還沒有達成一致的處理意見;如果需求變更的總體數量過高,則意味著項目范圍并未很好地確定下來或是政策變化較大。
            使用需求管理工具:需求變更控制委員會可以采取商業化的需求管理工具,以此來在數據庫中存儲不同類型的需求。這些工具提供了對每項需求的屬性描述,狀態跟蹤等,并可以在需求與其它的相關工作產品建立跟蹤能力聯系鏈。
            開發
            這里的開發指的就是如何在項目的開發過程中有效實施需求變更管理。實施需求變更管理需要遵循如下三個階段的原則:
            需求變更的前緒工作:
            1.項目的高效進行,需要良好的高質量的需求,同時它也是需求變更的依據。
            2.建立以文檔形式存在的簡單、有效的變更控制流程。
            3.建立項目變更管理執行小組及變更控制委員會。委員會成員組成涉及項目的多方人員,至少應包括用戶方代表和開發方的決策人員。小組成員可以由負責需求的人員中有經驗的需求分析員來擔當。
            需求變更進行時:
            需求變更的流程一定要遵循由變更控制委員會制定的變更控制流程。變更控制一般要經過變更申請、變更評估、委員會決策、委員會回復、實施變更、變更驗證六個步驟。
            1.變更申請:隨著項目的深入,需求變更也是不可避免的。需求分析小組一定要在充分考慮用戶需求,項目進度,需求基線的基礎上提交變更申請,并提供盡可能詳細的說明以供變更控制委員會進行變更評估。
            2.變更評估:需要對提出的變更需求進行影響分析,評估變更是否在項目范圍內,對項目計劃安排和其它需求的影響,需要的工作量等等。
            3.委員會決策:根據評估作出決策以確定選擇哪些,放棄哪些,并設置實現的優先順序,制定目標版本。
            4.委員會回復:回復包括同意實施變更和拒絕實施變更,并制定相應變更方案或說明拒絕理由。
            5.實施變更:維護需求變更文檔,包括:日期以及所做的變更、原因、負責人及新的版本號等等。該工作可以由委員會或者責成執行小組來完成。
            6.變更驗證:充分和提交變更申請人進行溝通,以使其得到滿意答復。然后根據變更方案和需求基線,進行相應的需求變更后的工作。該工作可以由執行小組來完成。
           需求變更后:
            參照需求跟蹤能力矩陣找到受需求變更影響的工作產品,并進行一致性變更,同時要維護變更歷史記錄。所有這些工作也是至關重要的內容,需要慎重細致對待,否則對持續的需求變更來講,將是一場災難。
            項目結束
            一個項目的交付驗收,并不意味著項目的真正結束,一個優秀的項目管理人員善于在項
            目結束后進行總結。項目總結工作當然要包括那些沒有預料到而發生的需求變更,以及這些變更的應對措施。根據實際工作中遇到的需求變更管理的問題,筆者總結如下幾點,以供參考和交流:
            ◆良好氣氛下的充分交流 討論需求及變更需求時,需求人員與客戶及用戶應該盡量采取協作的態度,良好的工作氛圍也會提高工作效率,很難想象雙方在“刁難”與“對付”的態度下是一種該有多糟糕的工作場景。確定需求基線的過程也就是與客戶用戶交流的過程,而頻繁大量的需求變更在很大程度上也是交流不充分的后果。所以,有效的充分的交流尤為重要,需求人員認真聽取客戶用戶的要求,進行分析和整理。同時還應該有能力設想項目的開發過程中可能會遇到的由該需求導致的問題,同時要讓客戶認識到如果此時再提出需求變更,將會給整個項目帶來的各種影響和沖擊。
            ◆專職人員負責需求變更管理 在具有相當規模的項目中,專職的需求人員和由此組成的需求變更執行小組是項目穩定、進度良好的保證。沒有變更管理而直接由開發人員處理的需求變更將會給項目帶來毀滅性的災難。這些專職人員應該具有專業的需求分析技巧技能,針對用戶的變更需求,可以給用戶說明利弊,可以按緊迫程度為開發人員提供工作重點,同時, 他們應該還能控制需求變更的頻率。
            ◆明確合同約束,限制需求變更 需求在軟件項目中的地位已經越來越重要,需求變更給軟件開發帶來的影響也是有目共睹,甚至因為質量低下的需求或者頻繁無控制的需求變更而導致項目的失敗。因此,應該讓客戶明白需求變更給項目帶來的工期、成本等各方面的影響,在互相理解的基礎上增加合同條款,比如明確說明客戶可以提出需求變更的期限,超過期限的需求變更的具體處理細則(如增加開發費用等,需求變更與開發費用本身也是關聯的,這個要求并不過分)。
            ◆良好的軟件結構適應需求變更  優秀的軟件體系結構可以快速應對不同情況的需求變
            更,這樣就可以適當降低需求的基線(當然是在成本影響的允許范圍內),從而來提高客戶的滿意度。適應需求變更必須遵循一些設計原則,如松散耦合、合理的接口定義等,要力求減少會對接口入口參數產生變化。

          posted @ 2014-08-11 09:57 順其自然EVO 閱讀(242) | 評論 (0)編輯 收藏

          對日軟件開發過程中的質量管理

            質量管理活動背景
            開發人員對委托方提供的設計資料的理解程度直接影響著開發進度和質量,從過去的產品質量數據分析結果來看,編程錯誤和對設計資料的理解錯誤是產生質量問題的兩個主要原因。
            特別是對設計資料的理解錯誤如不從一開始就采取措施進行預防,對程序本身及其他程序的質量將可能產生較大的影響。針對這一點,系統開發事業本部大連開發部開 展了以“預防/消除設計資料理解錯誤”為主題的質量控制(QC)活動。隨著活動開展的深入,質量控制逐漸取得了明顯的成效。
            “預防/消除設計資料理解錯誤”質量活動經過
            1.2003年11月末,各開發項目組提出了各項目質量分析報告;
            2.在對質量報告進行分析后,發現設計資料理解錯誤是質量問題的原因之一;
            3.討論預防和消除設計資料理解錯誤問題的應對措施;
            4.2003年12月26日,召開以“預防/消除設計資料理解錯誤”為主題的質量活動發表大會;
            5.2004年1月以各項目組為單位實施“預防/消除設計資料理解錯誤”質量控制活動;
            6.2004年3月在第八屆NEC中國地區質量控制大會上進行了活動匯報;
            7.計劃于2004年6月,對本次質量管理活動的結果進行總結報告。
            設計資料理解錯誤的原因分析及預防/消除對策
            減少設計資料理解錯誤的建議
            1.對于設計者的建議(依賴事項)
           ?。?)明確實現的功能,對處理的條件要充分描述。
           ?。?)充分地對設計書進行審查。
           ?。?)對編程前或編程中發生的問題,由設計人員到編程現場或通過網絡會議進行設計及原因說明。
            2.對于開發者的建議
           ?。?)加強審查 !
           ?。?)加強確認 !
           ?。?)加強溝通 !

          posted @ 2014-08-11 09:56 順其自然EVO 閱讀(179) | 評論 (0)編輯 收藏

          TestNg測試框架使用

          安裝Eclipse插件
            For Eclipse 3.4 and above, enter http://beust.com/eclipse.
            For Eclipse 3.3 and below, enter http://beust.com/eclipse1.
            Maven支持TestNG
          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <groupId>com.homeinns.web</groupId>
          <artifactId>homeinns-testng</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <packaging>jar</packaging>
          <name>homeinns-testng</name>
          <url>http://maven.apache.org</url>
          <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          </properties>
          <dependencies>
          <dependency>
          <groupId>org.testng</groupId>
          <artifactId>testng</artifactId>
          <version>6.1.1</version>
          <scope>test</scope>
          </dependency>
          </dependencies>
          <build>
          <plugins>
          <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.16</version>
          <configuration>
          <suiteXmlFiles>
          <suiteXmlFile>testng.xml</suiteXmlFile>
          <!-- <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> -->
          </suiteXmlFiles>
          </configuration>
          </plugin>
          </plugins>
          </build>
          </project>
           配置TestNg suite
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
          <suite name="Suite" parallel="none">
          <!--enabled="true"讓測試生效,也可根據情況關閉某些測試 -->
          <test name="Test" enabled="true">
          <!--指定參數 -->
          <parameter name="Name" value="Irving" />
          <parameter name="Sex" value="Man" />
          <!--指定測試包 -->
          <packages>
          <package name="com.homeinns.web.testng.*" />
          </packages>
          <!--指定測試類 -->
          <classes>
          <class name="com.homeinns.web.testng.AppTest" />
          </classes>
          </test> <!-- Test -->
          </suite> <!-- Suite -->
          TestNg注解配置
          public class NgTest {
          @Test
          public void f() {
          }
          @Test(
          // 在指定的時間內啟用3個線程并發測試本方法10次
          threadPoolSize = 3, invocationCount = 10, timeOut = 10000,
          // 等待測試方法t0測試結束后開始本測試
          dependsOnMethods = { "f" },
          // 指定測試數據源CLASS和數據源名稱(參考注解@DataProvider),返回幾條數據會跑測試方法幾次
          dataProvider = "generate", dataProviderClass = GeneratorRandomNum.class,
          // 分組名稱
          groups = { "checkin-test" })
          // 讀取配置文件中的參數,配置如上,用@Optional設置默認值
          @Parameters({ "Name" })
          public void f1(@Optional("name") String name) {
          }
          }
            測試報告
            運行測試后 在my-testng/test-output/ 目錄下(maven \target\surefire-reports)
            gradle配置
          subprojects {
          apply plugin: 'java'
          // Disable the test report for the individual test task
          test {
          reports.html.enabled = false
          }
          }
          task testReport(type: TestReport) {
          destinationDir = file("$buildDir/reports/allTests")
          //Include the results from the `test` task in all subprojects
          reportOn subprojects*.test
          }Grouping TestNG tests
          test {
          useTestNG {
          excludeGroups 'integrationTests'
          includeGroups 'unitTests'
          }
          }

          posted @ 2014-08-11 09:46 順其自然EVO 閱讀(536) | 評論 (0)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 68 69 70 71 72 73 74 75 76 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          • 隨筆 - 3936
          • 文章 - 404
          • 評論 - 179
          • 引用 - 0

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 绥芬河市| 屏东市| 蛟河市| 丽江市| 聂荣县| 保山市| 民权县| 汉中市| 灵石县| 淮北市| 仙游县| 吉安市| 武汉市| 万年县| 阳春市| 永安市| 东乡县| 广灵县| 平泉县| 陇西县| 同仁县| 中山市| 宁安市| 库伦旗| 凤庆县| 绥滨县| 固原市| 新泰市| 尼勒克县| 新密市| 台东市| 安达市| 武城县| 长武县| 手机| 武川县| 吴江市| 桦川县| 镇赉县| 东宁县| 新民市|