今天,基于神經網絡的人工智能正處于一個非常有趣的發展階段。它顯然已經起飛:我們看到從讀取CT掃描到采摘水果的許多應用。但采用率差異很大。推薦引擎、客戶支持機器人和其他被稱為“互聯網 AI”的東西相當普遍;我們在生活中隨處可見它。然而,大多數領域,包括軟件測試,還沒有完全實現。
是什么讓人工智能被廣泛采用,是什么讓它陷入困境?讓我們來看看我們自己的領域,軟件測試。具體來說,我想看看神經網絡如何生成自動化測試,以及在我們的領域大規模采用人工智能存在哪些障礙。我將首先關注問題和困難,不是因為我試圖成為半空的玻璃杯,而是因為出錯的事情總是告訴我們更多關于系統如何運作的信息,而不是正確的事情。
一旦我們完成了生成測試,我想看看人工智能在其他領域的應用,比如醫學——那里有很多工作要做,尤其是閱讀掃描。也許他們有類似的成長痛苦?最后,為了鳥瞰,我將看看一個完全不同的行業,它已經成熟和鞏固。它的經驗能告訴我們今天人工智能的發展嗎?
有了這個角度,也許我們可以停止困擾新技術的炒作/幻滅鐘擺,也許可以瞥見人工智能的發展方向。
確認
在我們繼續之前,我要感謝納塔利婭·波利亞科娃和阿爾喬姆·埃羅申科為我提供了這篇文章的時間和專業知識。但是,所寫一切的責任完全在于我。
另外,非常感謝Danil Churakov在此(和其他)帖子中提供的精彩圖片!
生成測試:現在的位置
今天,ChatGPT,GitHub Copilot和其他AI驅動的工具被廣泛用于編寫代碼和測試,我們最近對此進行了一次非常有趣的采訪。然而,人們仍然大多是手工編寫自動化測試,神經網絡的使用主要是情境化的。他們在這一領域達到目標的速度仍然遠低于人類的標準。 2020 年末的一篇論文預測了測試中 62% 的斷言陳述,這絕對是一個值得吹噓的結果。根據GitHub Copilot的常見問題解答,它的建議在26%的時間內被接受。人們常說,它最好的用途是作為谷歌和StackOverflow的更快替代品。所以 - 情境用法。目前,軟件QA中的AI還不能與營銷等領域擁有相同的水平,在市場營銷中,神經網絡創建的數字營銷和數據分析策略實際上優于人類創建的數字營銷和數據分析策略。但是,請記住,GPT-4 可能會改變情況。
這些問題從何而來?讓我們四處打聽并做一些實際研究。我和我經驗豐富的測試人員同事談過,也修改了Machinet,這是一個非常流行的IDEA插件,可以生成單元測試。
我們使用的神經網絡對于其預期應用非常有用。Machinet可能是作為開發人員助手而不是通用工具創建的。他們的座右銘聽起來絕對像是針對開發人員而不是QA:“讓我們面對現實吧。單元測試是一件苦差事。只需自動化即可。這是有道理的——通常是開發人員編寫單元測試。對于沒有深入了解測試的人來說,該工具做得很好。只有當我們從 QA 的角度來看待結果時,故障才會變得可見。那么存在哪些問題呢?
A. 問題
工作中的網絡
過度承保
Machinet 插件完成了它的工作,并且做得很徹底 - 它確保覆蓋 if-else 分支、使用不同的數據類型、檢查字符限制等。事實上,它完成的工作太徹底了,可以生成太多的測試,而不考慮資源負載。例如,檢查字段是否接受任何字符并檢查它是否將字符串長度限制為 255 個字符可以在單個測試中輕松完成 - 但 Machinet 為每種情況生成了一個單獨的測試。另一個示例涉及由多個 API 方法使用的數據檢索功能。生成的測試將涵蓋每個方法中的函數,并且將為函數本身創建一個單獨的測試。同樣,我們顯然得到了過度的報道。
印象是,如果我們有幾個相交的數據集,插件將嘗試覆蓋所有可能的交集。假設您正在測試一個電子商務網站,并且您有多種交付選項(客戶取貨、付款類型等)。使用Machinet,所有可能的組合都可能會被測試,而人類測試人員可以使用決策表來涵蓋真正重要的組合。但是,這樣做可能需要未輸入神經網絡的上下文數據。
代碼重復
一個相關的問題是代碼重復。我們正在測試一個需要填充對象的集合,它必須在 4 個不同的測試中使用。每個測試都從頭開始重新創建集合,而不是將其移動到單獨的字段或函數中。此外,代碼中已經存在一個用于生成集合的函數,它執行的操作與測試中所做的基本相同,但插件沒有使用它。神經網絡能很好地使用本地的東西?很容易說,嗯,這是網絡以前從未遇到過的獨特情況。但這并不像神經網絡在識別它以前見過的獨特貓照片時會遇到任何困難。這是一個有趣的問題,我們將在下面回到。
了解復雜代碼
神經網絡生成的自動化測試在涵蓋簡單的模塊化代碼片段時處于最佳狀態。當然,如果所有代碼都以這種方式編寫,那就太好了,但這可能是不可能的或不可行的。當您需要涵蓋冗長而復雜的業務邏輯時,機器生成的測試的可靠性會受到很大影響。當然,它們會被生成,但很難弄清楚它們是否正確地覆蓋了東西,或者它是否只是隨機的東西,幾乎不能指望用于煙霧測試。
了解上下文
在談到過度覆蓋時,我已經談到了這一點:網絡并不真正知道該方法的用途,因此無法根據這些知識進行優化。例如,人類測試人員知道,如果我們在 Java 中測試 API 方法,我們應該檢查空值;如果不是 API,則可以跳過此操作。我們看到的網絡似乎不會做出這樣的決定。
外部工具和模式的使用
我們還注意到,Machinet 使用硬編碼值填充集合,而不是使用庫隨機生成數據。我不知道這是否是一個過分的要求,但有一個相關的問題:我們使用的神經網絡在外部依賴關系方面做得不好,使用模式也是一個問題。
清理
最后,網絡生成的代碼肯定需要徹底審查。當然,所有由人類編寫的代碼也需要審查,這是標準做法,基于AI的工具的創建者總是警告這一點。在開發此類工具時,絕對必須牢記這一點:會有很多來回,使編輯變得容易應該是首要考慮因素。但這可能是一個問題還有另一個原因。正如我所說,Machinet 似乎針對那些可能不太熟悉測試的開發人員;因此,審查機器工作的人可能無法糾正我剛才談到的所有缺陷。
問題背后的原因
因此,當需要深入了解本地項目時,我們一直在使用的工具并不那么好,不“理解”他們正在測試的方法的上下文,他們不擅長在重復或資源使用方面優化代碼,他們最擅長簡單和模塊化的代碼,他們創建的代碼也往往是這樣。
乍一看,這些似乎是相當深層次的問題,但也許這是因為我們在談論“理解”而不是在談論數據。毫不奇怪,如果沒有對 RAM 和 CPU 使用率的數據進行訓練,網絡就無法根據資源消耗優化代碼。ChatGPT 不了解您的特定項目,因為它沒有接受過培訓。最后,這些障礙不是代碼固有的,這只是一個經濟學問題:在特定數據集上訓練網絡是否可行。
更深層次的原因本身就是代碼嗎?
然而,這里有一個更深層次的問題:代碼與人類語言不同。這個問題已經得到了很好的研究,并且已經為自然語言開發的算法絆倒了一段時間。如果我們將自然語言與您主要“按原樣”使用的工具進行比較,那么編程語言就是您用來構建工具的工具,以構建工具來構建工具。它更加嵌套。
對XKCD最好的問候
程序員編寫的每個新函數或變量都有自己的名稱,這些名稱可能會變得非常長且難以理解 - 特別是Java因VariableNamesThatLookAndFeelLikeTrainWrecks而臭名昭著。
這意味著,例如,Ubuntu 的源代碼可以比大量的英語文本語料庫多兩個數量級的獨特“單詞”(嗯,標記)。這是一個非常大且非常稀疏的詞匯;對于任何算法來說,這兩者都是壞消息。生僻詞意味著要學習的數據較少,詞匯量會影響算法的速度和內存要求。
這些嵌套詞匯表也非常本地化。您在項目中使用的大多數單詞永遠不會看到外部。這就是封裝的重點:突出的東西越少,代碼就越容易使用。因此,您擁有特定于應用程序甚至開發人員的詞匯表。此外,人們使用的工具也在不斷變化,這也催生了新的詞匯。除此之外,還有風格:我們編寫的代碼可能非常固執己見。那是你剛剛寫的Pythonic嗎?還是你還在拖著你舊的Java習慣?同樣的問題可以用不同的方式解決,造成進一步的混亂。
因此,想象一下您的技術堆棧。你有你的語言(也許是幾種語言),你的框架,你的數據庫,你在前端和后端擁有的所有庫,以及你使用的模式,以及開發人員的特質。所有這些交叉上下文都嚴重限制了任何特定AI驅動工具的類似代碼的數量。因此,難怪這些工具在生成復雜代碼時會遇到麻煩。
問題很深,但還不夠深
當然,這是一個問題,但遠非不可克服。問題是,在由語言、框架、項目等定義的上下文中,代碼實際上比人類語言重復得多(另請參閱此處)。而那個重復的部分是占主導地位的部分。一項研究發現,大量 JavaScript 文件包含 2 萬個唯一標識符,但其中只有 4k 個負責所有事件中的 10%。
因此,這不是數據(我們的代碼)的深層問題,而是數據如何組織以及如何將其輸入工具的問題。也許可以通過使用一種訓練子詞而不是單詞的算法來解決。這樣的算法不必處理數百萬字長的詞匯表,但它會更耗費資源?;蛘撸苍S是關于擁有一個可以足夠快地重新估計的模型,以便它可以適應您的本地環境?;蛘撸苍S我們應該將上下文信息(如注釋)提供給算法。無論如何,答案始終是關于我們如何組織數據以及處理數據的速度。
饋送網絡
縮?。喝斯ぶ悄艿难葑?/strong>
讓我們試著把這些問題放在正確的角度,看看它們與人工智能在其他領域必須克服的困難相比如何。
無論如何,神經網絡的歷史圍繞著在更短的時間內處理更多的數據。這是我一開始不太明白的:對于神經網絡,數量就是質量;數據越多,答案就越復雜和準確。
幾乎只要有計算機,人們就一直在嘗試構建神經網絡,但在大部分時間里,人工智能被不同的學校主導,即“基于規則”的方法:告訴你的系統規則并觀察它的工作;如果失敗 - 請咨詢專家,制定新規則。相比之下,神經網絡根據它們處理的數據自己找出規則。那么,為什么網絡只是在過去一二十年才“起飛”呢?因為那時我們獲得了大規模的數據存儲(特別是云)、瘋狂的大量生成數據(通過物聯網等)和巨大的處理能力(尤其是 GPU 計算);就在那時,發生了幾項創新,大大提高了深度神經網絡的訓練效率,從 2000 年代中期的 Geoffrey Hinton 的工作到 2018 年變壓器的發明。長話短說,可以快速處理大量數據。
但僅僅擁有算法和硬件可能還不夠。醫療保健是一個收集和存儲大量數據的領域,一直在尋找尖端技術,并吸引大量投資。因此,在某些地方和某些領域(如眼科),人工智能已經進入日常使用也就不足為奇了。然而,在廣泛采用之前還有很長的路要走。在醫療保健領域,與編程不同,確實存在優于人類的模型,但它們大多停留在開發階段,并且在實施中不斷失敗。
原因是,與用于訓練模型的集合相比,現實生活中的數據是“臟的”。目前,醫院的數據都以不同的方式收集和存儲,醫院通常有幾個系統,除了通過pdf文件外,它們不會相互通信。當然,數據基礎設施因醫院而異,因此您無法構建任何大規模數據集。此外,患者可能與用于訓練模型的人口統計數據不同。此外,從業者使用的一些信號沒有數字化,這降低了模型的比較效率。在本地數據集上訓練模型時,存在患者保密問題。
進入狹窄的空間
一般來說,有兩種方法可以繞過這些障礙:使模型適合現實生活中的使用給我們帶來的狹窄空間,或者擴大空間。
用于訓練醫療保健中表現最佳的模型的大型數據集是通過由于專有原因無法在現實生活中重現的步驟創建的。因此,可以在局部環境中校準模型以提高其準確性,而合成數據集可用于保護機密性。
但是,如果不改變用于收集和存儲數據的基礎設施,所有這些都不可能非常有效。現有的系統必須能夠相互連接,數據應該像STRIDES倡議所提議的那樣存儲在異地,最重要的是,它必須變得更加統一。
不出所料,代碼和醫療保健中采用問題背后的原因非常不同。解決方案則不然。我們可以預期這些模型在重新訓練以適應當地環境方面會變得更便宜、更有效。我們可以改變組織數據的方式。為了使網絡更高效地處理代碼和測試,我們需要更標準化的編寫和存儲方式。我們認為的“干凈代碼”的許多實踐旨在使代碼對人類更具可讀性。也許我們現在需要的是使其對神經網絡更具可讀性的方法。
或者也許它更簡單。如果神經網絡可以生成簡單、重復的代碼,并且善于用測試來覆蓋它——那么也許我們讓它們做工作的兩面,完全忘記干凈的編碼實踐,而是專注于控制輸出的方法。
總結
當一項新技術出現時,有兩種采用途徑:首先,該技術試圖適應經濟中已經存在的一些角色;然后,經濟發生變化,以適應新技術的全面發展。第二條路徑意味著創建一個基礎設施網絡來支持該技術。如果你有汽車,你也會得到新道路的大規模建設,你會得到立法的變化,等等。如果你想要電動汽車,你需要充電器。
這是目前在QA中AI之前的兩條道路,可以幫助將技術與支持它所需的基礎設施相結合:
1. 制作能夠更好地適應當地環境的人工智能驅動工具,能夠在特定項目和技術堆棧上學習的工具
2. 使測試的組織方式適應神經網絡的要求
審核編輯:郭婷
評論