中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

運營說白了是什么意思珠海百度關(guān)鍵字優(yōu)化

運營說白了是什么意思,珠海百度關(guān)鍵字優(yōu)化,蘇州網(wǎng)絡(luò)科技公司建網(wǎng)站,做網(wǎng)站信息1. 測試分為兩種及詳細介紹測試書籍: 1.1 Unit Test : 單元測試 - test the business logic in your app : 測試應(yīng)用中的業(yè)務(wù)邏輯 1.2 UI Test : 界面測試 - test the UI of your app : 測試應(yīng)用中的界面 1.3 測試書籍網(wǎng)址:《Testing Swift》 https://www.hackingwithswift.c…

1. 測試分為兩種及詳細介紹測試書籍:

? 1.1 Unit Test : 單元測試

? - test the business logic in your app : 測試應(yīng)用中的業(yè)務(wù)邏輯

? 1.2 UI? Test :? 界面測試

? - test the UI of your app : 測試應(yīng)用中的界面

? 1.3 測試書籍網(wǎng)址:《Testing Swift》?icon-default.png?t=N7T8https://www.hackingwithswift.com/store/testing-swift

2. ViewModel 單元測試

? 2.1 創(chuàng)建 ViewModel,UnitTestingBootcampViewModel.swift

import Foundation
import SwiftUI
import Combine/// 單元測試 ViewModel
class UnitTestingBootcampViewModel: ObservableObject{@Published var isPremium: Bool@Published var dataArray: [String] = []@Published var selectedItem: String? = nillet dataService: NewDataServiceProtocolvar cancellable = Set<AnyCancellable>()init(isPremium: Bool, dataService: NewDataServiceProtocol = NewMockDataService(items: nil)) {self.isPremium = isPremiumself.dataService = dataService}/// 添加子項func addItem(item: String){// 為空不往下執(zhí)行g(shù)uard !item.isEmpty else { return }self.dataArray.append(item)}/// 選中項func selectItem(item: String){if let x = dataArray.first(where: {$0 == item}){selectedItem = x}else{selectedItem = nil}}/// 保存項func saveItem(item: String) throws{guard !item.isEmpty else{throw DataError.noData}if let x = dataArray.first(where: {$0 == item}){print("Save item here!!! \(x)")} else {throw DataError.itemNotFound}}/// 錯誤信息enum DataError: LocalizedError{case noDatacase itemNotFound}/// 請求返回數(shù)據(jù)func downloadWithEscaping() {dataService.downloadItemsWithEscaping { [weak self] returnedItems inself?.dataArray = returnedItems}}/// 下載用到的組合func downloadWithCombine() {dataService.downloadItemsWithCombine().sink { _ in} receiveValue: { [weak self] returnedItems inself?.dataArray = returnedItems}.store(in: &cancellable)}
}

? 2.2 創(chuàng)建測試文件

? ? 當創(chuàng)建項目時,沒有選擇 Include Tests/包含測試 選項時,需要添加文件去對應(yīng)項目,不然測試文件會報 No such module 'XCTest' 編譯錯誤

? ? 添加單元測試文件:

? ? 方法一 : 選擇項目 -> 菜單欄 Editor -> Add Target... -> 彈出對話框,選擇 Test 欄下 -> Unit Testing Bundle -> 填寫信息/可默認 -> Finish,完成創(chuàng)建單元測試文件。

? ? 方法二 : 選擇項目,點擊 PROJECT 列,最下的 + 按鈕,彈出對話框,選擇 Test 欄下 ,后面步驟與上一致

? ? 創(chuàng)建單元測試文件 UnitTestingBootcampViewModel_Tests.swift

import XCTest
import Combine
/// 導(dǎo)入項目
@testable import SwiftfulThinkingAdvancedLearning// 《Testing Swift》 測試書籍
// 書籍網(wǎng)址: https://www.hackingwithswift.com/store/testing-swift
// Naming Structure: test_UnitOfWork_StateUnderTest_ExpectedBehavior -  結(jié)構(gòu)體命名: 測試_工作單元_測試狀態(tài)_預(yù)期的行為
// Naming Structure: test_[struct or class]_[variable or function]_[expected result] - 測試_[結(jié)構(gòu)體 或者 類的名稱]_[類中的變量名 或者 函數(shù)名稱]_[預(yù)期結(jié)果 預(yù)期值]
// Testing Structure: Given, When, Then - 測試結(jié)構(gòu): 給定,什么時候,然后final class UnitTestingBootcampViewModel_Tests: XCTestCase {/// 解決多次引用相同的類var viewModel: UnitTestingBootcampViewModel?var cancellables = Set<AnyCancellable>()/// 開始設(shè)置數(shù)據(jù)override func setUpWithError() throws {// Put setup code here. This method is called before the invocation of each test method in the class.viewModel = UnitTestingBootcampViewModel(isPremium: Bool.random())}/// 結(jié)束重置數(shù)據(jù)override func tearDownWithError() throws {// Put teardown code here. This method is called after the invocation of each test method in the class.viewModel = nilcancellables.removeAll()}/// 單元測試函數(shù)名,根據(jù)命名規(guī)則命名:測試_類名稱_是否高質(zhì)量_應(yīng)該為真func test_UnitTestingBootcampViewModel_isPremium_shouldBeTrue(){// Givenlet userIsPremium: Bool = true// Whenlet vm = UnitTestingBootcampViewModel(isPremium: userIsPremium)// ThenXCTAssertTrue(vm.isPremium)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名:測試_類名稱_是否高質(zhì)量_應(yīng)該為假func test_UnitTestingBootcampViewModel_isPremium_shouldBeFalse(){// Givenlet userIsPremium: Bool = false// Whenlet vm = UnitTestingBootcampViewModel(isPremium: userIsPremium)// ThenXCTAssertFalse(vm.isPremium)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名:測試_類名稱_是否高品質(zhì)_注入值func test_UnitTestingBootcampViewModel_isPremium_shouldBeInjectedValue(){// Givenlet userIsPremium: Bool = Bool.random()// Whenlet vm = UnitTestingBootcampViewModel(isPremium: userIsPremium)// ThenXCTAssertEqual(vm.isPremium, userIsPremium)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 注入值_壓力 / for 循環(huán)func test_UnitTestingBootcampViewModel_isPremium_shouldBeInjectedValue_stress(){for _ in 0 ..< 10 {// Givenlet userIsPremium: Bool = Bool.random()// Whenlet vm = UnitTestingBootcampViewModel(isPremium: userIsPremium)// ThenXCTAssertEqual(vm.isPremium, userIsPremium)}}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 數(shù)組_預(yù)期值:為空func test_UnitTestingBootcampViewModel_dataArray_shouldBeEmpty(){// Given// Whenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Then 斷言 = 判定XCTAssertTrue(vm.dataArray.isEmpty)XCTAssertEqual(vm.dataArray.count, 0)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 數(shù)組_預(yù)期值:添加項func test_UnitTestingBootcampViewModel_dataArray_shouldAddItems(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet loopCount: Int = Int.random(in: 1..<100)for _ in 0 ..< loopCount{vm.addItem(item: UUID().uuidString)}// Then 斷言 = 判定XCTAssertTrue(!vm.dataArray.isEmpty)XCTAssertFalse(vm.dataArray.isEmpty)XCTAssertEqual(vm.dataArray.count, loopCount)XCTAssertNotEqual(vm.dataArray.count, 0)// GreaterThan 大于XCTAssertGreaterThan(vm.dataArray.count, 0)// XCTAssertGreaterThanOrEqual// XCTAssertLessThan// XCTAssertLessThanOrEqual}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 數(shù)組_預(yù)期值:添加空白字符func test_UnitTestingBootcampViewModel_dataArray_shouldNotAddBlankString(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenvm.addItem(item: "")// Then 斷言 = 判定XCTAssertTrue(vm.dataArray.isEmpty)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 數(shù)組_預(yù)期值:添加空白字符func test_UnitTestingBootcampViewModel_dataArray_shouldNotAddBlankString2(){// Givenguard let vm = viewModel else {XCTFail()return}// Whenvm.addItem(item: "")// Then 斷言 = 判定XCTAssertTrue(vm.dataArray.isEmpty)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 選中項_預(yù)期值:開始為空func test_UnitTestingBootcampViewModel_selectedItem_shouldStartAsNil(){// Given// Whenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Then 斷言 = 判定XCTAssertTrue(vm.selectedItem == nil)XCTAssertNil(vm.selectedItem)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 選中項_預(yù)期值:應(yīng)該為空 當選擇無效項func test_UnitTestingBootcampViewModel_selectedItem_shouldBeNilWhenSelectingInvalidItem(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Select valid item : 選擇有效項let newItem = UUID().uuidStringvm.addItem(item: newItem)vm.selectItem(item: newItem)// Select invalid item : 選擇無效項// Whenvm.selectItem(item: UUID().uuidString)// Then 斷言 = 判定XCTAssertNil(vm.selectedItem)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 選中項_預(yù)期值:應(yīng)該選中func test_UnitTestingBootcampViewModel_selectedItem_shouldBeSelected(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet newItem = UUID().uuidStringvm.addItem(item: newItem)vm.selectItem(item: newItem)// Then 斷言 = 判定XCTAssertNotNil(vm.selectedItem)XCTAssertEqual(vm.selectedItem, newItem)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 選中項_預(yù)期值:選中_壓力測試func test_UnitTestingBootcampViewModel_selectedItem_shouldBeSelected_stress(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet loopCount: Int = Int.random(in: 1..<100)var itemsArray: [String] = []for _ in 0 ..< loopCount {let newItem = UUID().uuidStringvm.addItem(item: newItem)itemsArray.append(newItem)}// 隨機取一個字符串let randomItem = itemsArray.randomElement() ?? ""// 檢查字符串不為空XCTAssertFalse(randomItem.isEmpty)vm.selectItem(item: randomItem)// Then 斷言 = 判定XCTAssertNotNil(vm.selectedItem)XCTAssertEqual(vm.selectedItem, randomItem)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 保存項_預(yù)期值:輸出錯誤異常_元素沒找到func test_UnitTestingBootcampViewModel_saveItem_shouldThrowError_itemNotFound(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet loopCount: Int = Int.random(in: 1..<100)for _ in 0 ..< loopCount {vm.addItem(item: UUID().uuidString)}// Then 斷言 = 判定XCTAssertThrowsError(try vm.saveItem(item: UUID().uuidString))XCTAssertThrowsError(try vm.saveItem(item: UUID().uuidString), "Should throw Item Not Found error!") { error in// 返回錯誤let returnedError = error as? UnitTestingBootcampViewModel.DataError// 判斷錯誤是否相同XCTAssertEqual(returnedError, UnitTestingBootcampViewModel.DataError.itemNotFound)}}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 保存項_預(yù)期值:輸出錯誤異常_沒數(shù)據(jù)func test_UnitTestingBootcampViewModel_saveItem_shouldThrowError_noData(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet loopCount: Int = Int.random(in: 1..<100)for _ in 0 ..< loopCount {vm.addItem(item: UUID().uuidString)}// Then 斷言 = 判定do {try vm.saveItem(item: "")} catch let error {// 返回錯誤let returnedError = error as? UnitTestingBootcampViewModel.DataError// 判斷錯誤是否相同XCTAssertEqual(returnedError, UnitTestingBootcampViewModel.DataError.noData)}}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 保存項_預(yù)期值:保存選項func test_UnitTestingBootcampViewModel_saveItem_shouldSaveItem(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet loopCount: Int = Int.random(in: 1..<100)var itemsArray: [String] = []for _ in 0 ..< loopCount {let newItem = UUID().uuidStringvm.addItem(item: newItem)itemsArray.append(newItem)}// 隨機取一個字符串let randomItem = itemsArray.randomElement() ?? ""// 檢查字符串不為空XCTAssertFalse(randomItem.isEmpty)// Then 斷言 = 判定XCTAssertNoThrow(try vm.saveItem(item: randomItem))do {try vm.saveItem(item: randomItem)} catch  {XCTFail()}}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 下載數(shù)據(jù)_預(yù)期值:返回選項func test_UnitTestingBootcampViewModel_downloadWithEscaping_shouldReturnItems(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet expectation = XCTestExpectation(description: "Should return items after 3 seconds")// dropFirst: 刪除第一個發(fā)布 數(shù)組值,因為初始化為空數(shù)組,取的是第二個數(shù)組,模擬服務(wù)數(shù)據(jù)返回的數(shù)組vm.$dataArray.dropFirst().sink { returnedItems inexpectation.fulfill()}.store(in: &cancellables)vm.downloadWithEscaping()// Then 斷言 = 判定 GreaterThan:大于// 為了安全獲取到值,設(shè)置等待 5 秒wait(for: [expectation], timeout: 5)XCTAssertGreaterThan(vm.dataArray.count, 0)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 下載數(shù)據(jù)組合_預(yù)期值:返回選項func test_UnitTestingBootcampViewModel_downloadWithCombine_shouldReturnItems(){// Givenlet vm = UnitTestingBootcampViewModel(isPremium: Bool.random())// Whenlet expectation = XCTestExpectation(description: "Should return items after a seconds")// dropFirst: 刪除第一個發(fā)布 數(shù)組值,因為初始化為空數(shù)組,取的是第二個數(shù)組,模擬服務(wù)數(shù)據(jù)返回的數(shù)組vm.$dataArray.dropFirst().sink { returnedItems inexpectation.fulfill()}.store(in: &cancellables)vm.downloadWithCombine()// Then 斷言 = 判定 GreaterThan:大于// 為了安全獲取到值,設(shè)置等待 5 秒wait(for: [expectation], timeout: 5)XCTAssertGreaterThan(vm.dataArray.count, 0)}/// 單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 下載數(shù)據(jù)組合_預(yù)期值:返回選項func test_UnitTestingBootcampViewModel_downloadWithCombine_shouldReturnItems2(){// Givenlet items: [String] = [UUID().uuidString, UUID().uuidString, UUID().uuidString, UUID().uuidString]let dataService: NewDataServiceProtocol = NewMockDataService(items: items)let vm = UnitTestingBootcampViewModel(isPremium: Bool.random(), dataService: dataService)// Whenlet expectation = XCTestExpectation(description: "Should return items after a seconds")// dropFirst: 刪除第一個發(fā)布 數(shù)組值,因為初始化為空數(shù)組,取的是第二個數(shù)組,模擬服務(wù)數(shù)據(jù)返回的數(shù)組vm.$dataArray.dropFirst().sink { returnedItems inexpectation.fulfill()}.store(in: &cancellables)vm.downloadWithCombine()// Then 斷言 = 判定 GreaterThan:大于// 為了安全獲取到值,設(shè)置等待 5 秒wait(for: [expectation], timeout: 5)XCTAssertGreaterThan(vm.dataArray.count, 0)XCTAssertEqual(vm.dataArray.count, items.count)}
}

3. 模擬請求數(shù)據(jù) 單元測試

? 3.1 創(chuàng)建模擬請求數(shù)據(jù)類 NewMockDataService.swift

import Foundation
import SwiftUI
import Combine/// 定義協(xié)議
protocol NewDataServiceProtocol{func downloadItemsWithEscaping(completion: @escaping (_ items: [String]) -> ())func downloadItemsWithCombine() -> AnyPublisher<[String], Error>
}/// 實現(xiàn)模擬請求數(shù)據(jù)
class NewMockDataService: NewDataServiceProtocol {let items: [String]init(items: [String]?) {self.items = items ?? ["ONE", "TWO", "THREE"]}/// 模擬網(wǎng)絡(luò)下載數(shù)據(jù) escaping: 轉(zhuǎn)義字符func downloadItemsWithEscaping(completion: @escaping (_ items: [String]) -> ()) {DispatchQueue.main.asyncAfter(deadline: .now() + 2) {completion(self.items)}}/// 下載組合func downloadItemsWithCombine() -> AnyPublisher<[String], Error> {// 數(shù)據(jù)轉(zhuǎn)換Just(self.items).tryMap({ publishedItems inguard !publishedItems.isEmpty else {throw URLError(.badServerResponse)}return publishedItems}).eraseToAnyPublisher()}
}

? 3.2 創(chuàng)建單元測試類 NewMockDataService_Tests.swift

import XCTest
import Combine
/// 導(dǎo)入項目
@testable import SwiftfulThinkingAdvancedLearningfinal class NewMockDataService_Tests: XCTestCase {/// 隨時取消控制器var cancellable = Set<AnyCancellable>()override func setUpWithError() throws {// Put setup code here. This method is called before the invocation of each test method in the class.}override func tearDownWithError() throws {// Put teardown code here. This method is called after the invocation of each test method in the class.cancellable.removeAll()}//  單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 測試_類名_初始化_預(yù)期值:正確的設(shè)置值func test_NewMockDataService_init_doesSetValuesCorrectly() {// 執(zhí)行// Given: 給定let items: [String]? = nillet items2: [String]? = []let items3: [String]? = [UUID().uuidString, UUID().uuidString]// When: 時間let dataService = NewMockDataService(items: items)let dataService2 = NewMockDataService(items: items2)let dataService3 = NewMockDataService(items: items3)// Then 然后XCTAssertFalse(dataService.items.isEmpty)XCTAssertTrue(dataService2.items.isEmpty)XCTAssertEqual(dataService3.items.count, items3?.count)}//  單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 測試_類名_下載轉(zhuǎn)換數(shù)據(jù)項_預(yù)期值:正確的設(shè)置值func test_NewMockDataService_downloadItemsWithEscaping_doesReturnValues() {// 執(zhí)行// Given: 給定let dataService = NewMockDataService(items: nil)// When: 時間var items: [String] = []let expectation = XCTestExpectation()dataService.downloadItemsWithEscaping { returnedItems initems = returnedItemsexpectation.fulfill()}// Then 然后// 等待 5 秒wait(for: [expectation], timeout: 5)// 斷言兩個數(shù)組大小一樣XCTAssertEqual(items.count, dataService.items.count)}//  單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 測試_類名_下載數(shù)據(jù)項組合_預(yù)期值:正確的設(shè)置值func test_NewMockDataService_downloadItemsWithCombine_doesReturnValues() {// 執(zhí)行// Given: 給定let dataService = NewMockDataService(items: nil)// When: 時間var items: [String] = []let expectation = XCTestExpectation()// 下載組合控制dataService.downloadItemsWithCombine().sink { completion inswitch completion{case .finished:expectation.fulfill()case .failure:XCTFail()}} receiveValue: {returnedItems in// fulfill: 完成items = returnedItems}.store(in: &cancellable)// Then 然后// 等待 5 秒wait(for: [expectation], timeout: 5)// 斷言兩個數(shù)組大小一樣XCTAssertEqual(items.count, dataService.items.count)}//  單元測試函數(shù)名 根據(jù)命名規(guī)則命名 - 測試_類名_下載數(shù)據(jù)項組合_預(yù)期值:確實失敗func test_NewMockDataService_downloadItemsWithCombine_doesFail() {// 執(zhí)行// Given: 給定let dataService = NewMockDataService(items: [])// When: 時間var items: [String] = []let expectation = XCTestExpectation(description: "Does throw an error")let expectation2 = XCTestExpectation(description: "Does throw URLError.badServerResponse")// 下載組合控制dataService.downloadItemsWithCombine().sink { completion inswitch completion{case .finished:XCTFail()case .failure(let error):expectation.fulfill()//let urlError = error as? URLError// 斷言,判定//XCTAssertEqual(urlError, URLError(.badServerResponse))// 錯誤判斷if error as? URLError == URLError(.badServerResponse) {expectation2.fulfill()}}} receiveValue: {returnedItems in// fulfill: 完成items = returnedItems}.store(in: &cancellable)// Then 然后// 等待 5 秒wait(for: [expectation, expectation2], timeout: 5)// 斷言兩個數(shù)組大小一樣XCTAssertEqual(items.count, dataService.items.count)}
}

4. 創(chuàng)建單元測試 View,調(diào)用測試的 ViewModel UnitTestingBootcampView.swift

import SwiftUI/*1. Unit Test : 單元測試- test the business logic in your app : 測試應(yīng)用中的業(yè)務(wù)邏輯2. UI  Test :  界面測試- test the UI of your app : 測試應(yīng)用中的界面*//// 單元測試
struct UnitTestingBootcampView: View {@StateObject private var vm: UnitTestingBootcampViewModelinit(isPremium: Bool){_vm = StateObject(wrappedValue: UnitTestingBootcampViewModel(isPremium: isPremium))}var body: some View {Text(vm.isPremium.description)}
}struct UnitTestingBootcampView_Previews: PreviewProvider {static var previews: some View {UnitTestingBootcampView(isPremium: true)}
}
http://www.risenshineclean.com/news/51495.html

相關(guān)文章:

  • 醫(yī)療器械做網(wǎng)站備案創(chuàng)建網(wǎng)站需要多少資金
  • 中國建設(shè)銀行官方網(wǎng)站首頁全網(wǎng)推廣的方式有哪些
  • 用美圖秀秀做網(wǎng)站圖片軟文營銷的定義
  • 如何做單網(wǎng)頁網(wǎng)站抖音seo優(yōu)化公司
  • wordpress頁面自由布局神馬搜索seo優(yōu)化排名
  • 縣政府門戶網(wǎng)站建設(shè)方案品牌營銷公司
  • 企業(yè)網(wǎng)站的基本內(nèi)容騰訊第三季度營收448億元
  • 做網(wǎng)站賣廣告掙幾百萬建站模板平臺
  • 南昌新建網(wǎng)站建設(shè)南京網(wǎng)絡(luò)推廣公司排名
  • 網(wǎng)站建設(shè)小組搜索引擎優(yōu)化方式
  • 網(wǎng)站開發(fā)包含哪些網(wǎng)站下載
  • 免費建站網(wǎng)站一級大陸在線看網(wǎng)站優(yōu)化推廣培訓(xùn)
  • 鞍山市住房和城鄉(xiāng)建設(shè)網(wǎng)站中國有幾個搜索引擎
  • 最優(yōu)的錦州網(wǎng)站建設(shè)專門搜索知乎內(nèi)容的搜索引擎
  • 網(wǎng)站建設(shè)個人網(wǎng)站網(wǎng)站頁面優(yōu)化包括
  • 網(wǎng)站建設(shè)的項目計劃書網(wǎng)店運營實訓(xùn)報告
  • 外國人的做視頻網(wǎng)站嗎搜搜
  • 網(wǎng)站全景看圖怎么做網(wǎng)銷是做什么的
  • 個人網(wǎng)站有什么寧波seo推薦優(yōu)化
  • 免費設(shè)計室內(nèi)裝修app廈門seo結(jié)算
  • 廣州市建設(shè)和水務(wù)局網(wǎng)站全網(wǎng)搜索引擎優(yōu)化
  • 大連三豐建設(shè)集團公司網(wǎng)站四種營銷策略
  • 網(wǎng)站支持asp網(wǎng)絡(luò)營銷論文畢業(yè)論文
  • wordpress整站源碼網(wǎng)絡(luò)營銷的目的是什么
  • 南通高端網(wǎng)站建設(shè)開發(fā)百度站長資源平臺
  • access做網(wǎng)站數(shù)據(jù)庫能有多大容量百度競價什么意思
  • 如何訪問云南建設(shè)廳網(wǎng)站網(wǎng)站服務(wù)器是什么意思
  • 濟南網(wǎng)站建設(shè)企業(yè)談?wù)勀銓W(wǎng)絡(luò)營銷的看法
  • 兩個網(wǎng)站共用一個空間搜索引擎排名中國
  • 太原網(wǎng)站建設(shè)與維護做網(wǎng)站的平臺