什么是混合應用
移動端應用有兩種典型的開發方式,一種是原生的 native app,一種是基于網頁開發技術的 web app。 原生應用的體驗感更好,但是如果想同時開發安卓應用和 ios 應用,需要不同的原生開發技術。 web 應用可以非常輕松的做到安卓和 ios 的跨平臺開發,它的體驗感要稍微差一些,不像原生應用那么流暢。
Hybrid App(混合模式移動應用)是介于 web app和native app之間的開發方式,可以在原生界面中嵌套網頁,因而可以同時具備體驗感和跨平臺能力。
目前主流的移動端 app 測試框架 appium 具備混合應用測試的能力,但是這個框架搭建和使用都比較麻煩,封裝的方法也沒有那么 pythonic,因此有很多公司不想使用,他們更加喜歡簡潔優雅的 python uiautomator2 框架。 非常遺憾,這個框架目前沒有支持混合應用測試。
混合應用測試步驟
第一步,通過原生操作進入 webview 網頁;
第二步,使用 selenium 等網頁測試工具進入網頁;
第三步,使用 selenium 等網頁測試工具測試。
這中間的關鍵步驟在于如何使用 selenium, 如果直接打開一個新的 selenium 會話,那么會打開一個新的頁面,和 app 中的 webview 是分開的,因此無法測到嵌套網頁。 selenium 必須要和 app 建立某種關系,使他們綁定在一起,操作 selenium 時就是直接操作 app 當中的網頁。
通過 uiautomator2 進入 webview
這里就是最基本的 uiautomator2 操作,詳細操作可以查看官方文檔, 這里使用的 app 是 android bootstrap 。
d=u2.connect()
d.app_start('com.github.android_app_bootstrap')
d(text='Login').click()
d(text='Baidu').click()
selenium 連接 webview
APP 的第三個菜單可以直接打開 baidu 網頁,從而到 webview 網頁。 如果不使用 selenium 連接,直接通過 uiautomator2 定位網頁中的元素,是會報錯的。
那如何通過 selenium 連接 webview 呢?
首先,通過設備 d 獲取當前操作的 app, 從而得到包名
然后,初始化一個 Chrome 瀏覽器對象
需要注意的是,Chrome 對象需要添加額外的參數,指定連接的設備,webview 綁定的報名,以及配置在 app 中使用 android 瀏覽器。
之后的操作就和 selenium 做 web 自動化測試沒有任何區別了,無非就是點擊網頁,做自動化操作:
driver=webdriver.Chrome('chromedriver_68.exe', options=options)
driver.implicitly_wait(8)
driver.find_element('id', 'index-kw').send_keys('你好')
這段代碼我在哪里學到的
是不是很好奇,我怎么知道要這么寫代碼,才能連接 webview ,達到測試效果? 其實世間沒有那么多神秘的學習方法,只要你肯用心,一定是可以找到學習的路徑的。 這段代碼清清楚楚的寫在 chrome webdriver 的官方文檔中,只是,你可能打不開。 截屏看一下:
其他 webdriver 的配置也可以查看 MDN web docs。
展示效果:
我們都知道對于桌面應用開發來說,人們常用的方式就是采用c++或者c#,java等進行開發,然而這些語言開發效率不夠高,不如網頁開發靈活。因此,人們思考能否采用html+css+js的方式來開發桌面客戶端呢,于是人們就提出了混合開發概念,并且開發了electron框架進行桌面開發。
提到electron開發的桌面應用,就不得不提vscode,這個采用css+js+html開發的編輯器從誕生以來就逐漸占據市場的份額,現在幾乎絕大部分的前端開發者都采用vscode進行開發,而且也有很多后端開發者逐漸采用vscode進行后端開發,可以說vscode證明了electron也可以開發出優秀的桌面程序。當然,除了vscode之外,whatsapp和twitch還有slack也是采用electron開發的。
webview2是微軟推出的一組控件,它可以讓本地應用程序輕松嵌入web技術。WebView2 控件使用Microsoft Edge作為呈現引擎在本機應用程序中顯示 Web 內容。使用 WebView2,您可以將 Web 代碼嵌入到本機應用程序的不同部分,或在單個 WebView 實例中構建所有本機應用程序。
Webview2 應用程序允許廣泛的覆蓋范圍。作為 Web 開發人員,您可以跨不同平臺重用大部分代碼。對于要訪問本機平臺的所有功能,則推薦直接使用本機應用程序。
之所以稱為 WebView2,是因為它取代了 WebView 控件,而后者又取代了 WebBrowser 控件,老派 Win32 開發人員可能還記得。WebView 使用原始的 Edge (Trident) 渲染引擎,是 Windows10 唯一的控件。WebView2 使用較新的 Edge 渲染引擎,并支持多種Windows 平臺。
Electron 為常見的桌面應用程序需求提供 API,例如菜單、文件系統訪問、通知等。
WebView2 是一個組件,旨在集成到 WinForms、WPF、WinUI 或 Win32 等應用程序框架中。
Node.js 被集成到 Electron 中。Electron 應用程序可以使用來自渲染器和主進程的 Node.js API、模塊或 node-native-addon。
WebView2 應用程序支持嵌入到多種編程語言之中。您的 JavaScript 代碼必須通過應用程序主機進程代理執行訪問操作系統。
Electron 努力保持與 Web API 的兼容性。
Electron 具有可配置的 Web 內容安全模型,從完全訪問到完全沙盒。WebView2 內容始終被沙盒化.
目前的webview2還只是支持windows的各個版本預覽,未來,webview將會支持UWP 預覽 ,macOS 預覽,Xbox 預覽,HoloLens 預覽,Linux 預覽,總之,webview2未來可期。
pring Boot中,你可能想要基于動態內容生成靜態HTML頁面。有幾種方法可以實現這一目標,以下是其中的一些方法:
下面是一個使用Thymeleaf的簡單示例:
@Service
public class StaticHtmlGeneratorService {
@Autowired
private TemplateEngine templateEngine;
@Autowired
private ApplicationContext applicationContext;
public void generateStaticHtml(String templateName, Map<String, Object> context, String outputPath) {
Context thContext=new Context();
thContext.setVariables(context);
String processedHtml=templateEngine.process(templateName, thContext);
try (BufferedWriter writer=new BufferedWriter(new FileWriter(outputPath))) {
writer.write(processedHtml);
} catch (IOException e) {
// Handle exception
}
}
}
這段代碼不是完整的實現,因為TemplateEngine類并不是Spring Boot標準庫中的一部分。在實際應用中,你會使用具體的模板引擎的API(例如Thymeleaf的TemplateEngine),并相應地調整代碼。
實際上,Spring Boot集成Thymeleaf后,你會這樣使用Thymeleaf的API:
@Autowired
private SpringTemplateEngine templateEngine;
public void generateStaticHtml(String templateName, Map<String, Object> contextVars, String outputPath) {
Context context=new Context();
context.setVariables(contextVars);
String processedHtml=templateEngine.process(templateName, context);
// Write the processedHtml to a file
// ...
}
public void generateStaticHtmlWithJsoup(String title, String bodyContent, String outputPath) throws IOException {
Document doc=Jsoup.parse("<html><head><title></title></head><body></body></html>");
doc.title(title);
doc.body().append(bodyContent);
// 美化輸出(Pretty-print)
doc.outputSettings().prettyPrint(true);
// 寫入文件
Files.write(Paths.get(outputPath), doc.outerHtml().getBytes(StandardCharsets.UTF_8));
}
@Autowired
private RestTemplate restTemplate;
public void generateStaticHtmlFromWebService(String url, String outputPath) throws IOException {
ResponseEntity<String> response=restTemplate.getForEntity(url, String.class);
if (response.getStatusCode()==HttpStatus.OK) {
Files.write(Paths.get(outputPath), response.getBody().getBytes(StandardCharsets.UTF_8));
}
}
在生成靜態HTML時,請考慮以下幾點:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。