Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
HYH.APSJ
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
佟礼
HYH.APSJ
Commits
1ade661a
Commit
1ade661a
authored
Aug 21, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
POA
parent
e3a2cdde
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
425 additions
and
0 deletions
+425
-0
POAOrToolsModelTest.java
src/test/java/com/aps/demo/POAOrToolsModelTest.java
+391
-0
POAOrToolsModelTestRunner.java
src/test/java/com/aps/demo/POAOrToolsModelTestRunner.java
+34
-0
No files found.
src/test/java/com/aps/demo/POAOrToolsModelTest.java
0 → 100644
View file @
1ade661a
package
com
.
aps
.
demo
;
import
com.aps.entity.Algorithm.OperationDependency
;
import
com.aps.entity.Algorithm.OrderMaterialRequirement
;
import
com.aps.entity.basic.Entry
;
import
com.aps.entity.basic.Machine
;
import
com.aps.entity.basic.MachineOption
;
import
com.aps.poa.data.BomRelation
;
import
com.aps.poa.data.DataAdapter
;
import
com.aps.poa.data.InventoryConstraint
;
import
com.aps.poa.data.ModelConfig
;
import
com.aps.poa.data.OpDef
;
import
com.aps.poa.data.ResourceDef
;
import
com.aps.poa.data.SetupMatrix
;
import
com.aps.poa.data.SolveResult
;
import
com.aps.poa.model.POAOrToolsModel
;
import
com.google.ortools.Loader
;
import
org.junit.jupiter.api.BeforeAll
;
import
org.junit.jupiter.api.Test
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
/**
* POAOrToolsModel 可运行测试:
* 1. 业务实体版(Entry / Machine / materialRequirements 推导 BOM)
* 2. 内部模型版(OpDef / ResourceDef / 换型 / 时间窗 / 库存)
*/
class
POAOrToolsModelTest
{
@BeforeAll
static
void
init
()
{
Loader
.
loadNativeLibraries
();
}
@Test
void
testSolve_WithBusinessEntities
()
{
// ---- 1. 设备(Machine)----
List
<
Machine
>
machines
=
Arrays
.
asList
(
new
Machine
(
0
,
"M0"
),
new
Machine
(
1
,
"M1"
),
new
Machine
(
2
,
"M2"
)
);
// ---- 2. 工序(Entry):priority 设高 → 强制全规划 ----
List
<
Entry
>
entries
=
buildEntries
(
100
);
// ---- 3. BOM:J0 首工序消耗 J1、J2 半成品(materialRequirements)----
entries
.
get
(
0
).
setMaterialRequirements
(
Arrays
.
asList
(
bomReq
(
"J1"
),
bomReq
(
"J2"
)));
// ---- 4. 求解 ----
ModelConfig
cfg
=
new
ModelConfig
();
cfg
.
timeLimitSeconds
=
10
;
cfg
.
weightMakespan
=
1.0
;
cfg
.
weightUnplanned
=
1000.0
;
POAOrToolsModel
scheduler
=
new
POAOrToolsModel
(
entries
,
machines
,
cfg
);
scheduler
.
build
();
SolveResult
result
=
scheduler
.
solve
();
printResult
(
result
);
// ---- 5. 断言 ----
assertTrue
(
result
.
isFeasible
,
"模型应可行"
);
assertTrue
(
result
.
makespan
>
0
,
"makespan 应大于 0"
);
assertTrue
(
result
.
unscheduledOps
.
isEmpty
(),
"所有工序均应被规划,实际未规划: "
+
result
.
unscheduledOps
);
assertEquals
(
7
,
result
.
startTimes
.
size
(),
"应规划 7 道工序"
);
// 前序约束(prevEntryIds 映射):end(prev) <= start(curr)
assertOrder
(
"1"
,
"2"
,
result
);
// J0_O0 → J0_O1
assertOrder
(
"2"
,
"3"
,
result
);
// J0_O1 → J0_O2
assertOrder
(
"4"
,
"5"
,
result
);
// J1_O0 → J1_O1
assertOrder
(
"6"
,
"7"
,
result
);
// J2_O0 → J2_O1
// BOM 齐套(materialRequirements 推导):父首工序 >= max(子末工序 end)
assertTrue
(
result
.
startTimes
.
get
(
"1"
)
>=
Math
.
max
(
result
.
endTimes
.
get
(
"5"
),
result
.
endTimes
.
get
(
"7"
))
-
1
e
-
6
,
"BOM 齐套约束应满足(J0 首工序应晚于 J1/J2 末工序完工)"
);
}
@Test
void
testToOpDefs_EntryMapping
()
{
// 单工序:2 台候选设备 + 1 个前序依赖 + 优先级
List
<
Entry
>
entries
=
new
ArrayList
<>();
entries
.
add
(
op
(
101
,
"J0"
,
1
,
"成品-工序0"
,
5
,
opt
(
0L
,
12
),
opt
(
1L
,
10
)));
dep
(
entries
.
get
(
0
),
op
(
100
,
"J0"
,
0
,
"前序工序"
,
1
,
opt
(
0L
,
8
)));
List
<
OpDef
>
ops
=
DataAdapter
.
toOpDefs
(
entries
);
assertEquals
(
1
,
ops
.
size
(),
"应转换出 1 道工序"
);
OpDef
opDef
=
ops
.
get
(
0
);
assertEquals
(
"101"
,
opDef
.
id
,
"工序 ID 应为 Entry.id 的字符串"
);
assertEquals
(
"成品-工序0"
,
opDef
.
name
,
"工序名称应取自 routingDetailName"
);
assertEquals
(
2
,
opDef
.
candidateResources
.
size
(),
"应保留 2 台候选设备"
);
assertEquals
(
"0"
,
opDef
.
candidateResources
.
get
(
0
),
"候选设备1 应为 machineId=0"
);
assertEquals
(
"1"
,
opDef
.
candidateResources
.
get
(
1
),
"候选设备2 应为 machineId=1"
);
assertEquals
(
12.0
,
opDef
.
durations
.
get
(
0
),
1
e
-
6
,
"设备0 加工时长应为 12"
);
assertEquals
(
10.0
,
opDef
.
durations
.
get
(
1
),
1
e
-
6
,
"设备1 加工时长应为 10"
);
assertEquals
(
5000.0
,
opDef
.
unplannedCost
,
1
e
-
6
,
"未规划惩罚应为 priority(5) * 1000"
);
assertEquals
(
1
,
opDef
.
predecessors
.
size
(),
"应保留 1 个前序依赖"
);
assertEquals
(
0.0
,
opDef
.
predecessors
.
get
(
"100"
),
1
e
-
6
,
"前序依赖应为 prevOperationId=100"
);
}
@Test
void
testToOpDefs_NoMachineOptions_Throws
()
{
Entry
e
=
new
Entry
();
e
.
setId
(
1
);
e
.
setOrderId
(
"J0"
);
e
.
setSequence
(
1
);
assertThrows
(
IllegalArgumentException
.
class
,
()
->
DataAdapter
.
toOpDefs
(
Arrays
.
asList
(
e
)),
"工序没有候选设备时应抛出异常"
);
}
@Test
void
testToOpDefs_MultiInputProducts
()
{
// FG1 首工序(id=1) 消耗 SUB1(5) + SUB2(3) 两种物料;SUB1/SUB2 末工序各自产出
List
<
Entry
>
entries
=
new
ArrayList
<>();
entries
.
add
(
setMr
(
op
(
1
,
"FG1"
,
1
,
"成品-工序0"
,
100
,
opt
(
0L
,
6
),
opt
(
1L
,
5
)),
bomReq
(
"SUB1"
,
5
),
bomReq
(
"SUB2"
,
3
)));
entries
.
add
(
op
(
11
,
"SUB1"
,
1
,
"半成品1-工序0"
,
100
,
opt
(
0L
,
5
)));
entries
.
add
(
setProduct
(
op
(
12
,
"SUB1"
,
2
,
"半成品1-工序1"
,
100
,
opt
(
1L
,
7
)),
"SUB1"
,
5
));
entries
.
add
(
op
(
13
,
"SUB2"
,
1
,
"半成品2-工序0"
,
100
,
opt
(
0L
,
6
)));
entries
.
add
(
setProduct
(
op
(
14
,
"SUB2"
,
2
,
"半成品2-工序1"
,
100
,
opt
(
1L
,
7
)),
"SUB2"
,
3
));
List
<
OpDef
>
ops
=
DataAdapter
.
toOpDefs
(
entries
);
OpDef
fg1o0
=
ops
.
get
(
0
);
// 多物料消耗:inputProducts 应包含两个条目(修复前的单值 inputQty 会覆盖丢失)
assertEquals
(
2
,
fg1o0
.
inputProducts
.
size
(),
"工序应消耗 2 种物料"
);
assertEquals
(
5.0
,
fg1o0
.
inputProducts
.
get
(
"SUB1"
),
1
e
-
6
,
"应消耗 SUB1 数量 5"
);
assertEquals
(
3.0
,
fg1o0
.
inputProducts
.
get
(
"SUB2"
),
1
e
-
6
,
"应消耗 SUB2 数量 3"
);
// 产出映射:SUB1/SUB2 末工序
OpDef
sub1o1
=
ops
.
get
(
2
);
assertEquals
(
5.0
,
sub1o1
.
outputQty
,
1
e
-
6
,
"SUB1 末工序产出 5"
);
assertEquals
(
"SUB1"
,
sub1o1
.
productId
,
"SUB1 末工序产出产品 SUB1"
);
OpDef
sub2o1
=
ops
.
get
(
4
);
assertEquals
(
3.0
,
sub2o1
.
outputQty
,
1
e
-
6
,
"SUB2 末工序产出 3"
);
assertEquals
(
"SUB2"
,
sub2o1
.
productId
,
"SUB2 末工序产出产品 SUB2"
);
}
@Test
void
testToResourceDefs_MachineMapping
()
{
List
<
ResourceDef
>
res
=
DataAdapter
.
toResourceDefs
(
Arrays
.
asList
(
new
Machine
(
0
,
"M0"
),
new
Machine
(
5
,
"M5"
)));
assertEquals
(
2
,
res
.
size
(),
"应转换出 2 台设备"
);
assertEquals
(
"0"
,
res
.
get
(
0
).
id
,
"资源 ID 应为 Machine.id 的字符串"
);
assertEquals
(
"5"
,
res
.
get
(
1
).
id
,
"资源 ID 应为 Machine.id 的字符串"
);
}
@Test
void
testToBomRelations_FromMaterialRequirements
()
{
List
<
Entry
>
entries
=
buildEntries
(
100
);
// J0 首工序(id=1) 消耗 J1、J2 半成品 → 父首工序 ≥ 子末工序(id=5、7)
entries
.
get
(
0
).
setMaterialRequirements
(
Arrays
.
asList
(
bomReq
(
"J1"
),
bomReq
(
"J2"
)));
List
<
BomRelation
>
boms
=
DataAdapter
.
toBomRelations
(
entries
);
assertEquals
(
1
,
boms
.
size
(),
"应推导出 1 条 BOM 关系"
);
BomRelation
bom
=
boms
.
get
(
0
);
assertEquals
(
"1"
,
bom
.
parentFirstOpId
,
"父工序应为 J0 首工序(id=1)"
);
assertEquals
(
2
,
bom
.
childLastOpIds
.
size
(),
"应包含 2 个子工单末工序"
);
assertTrue
(
bom
.
childLastOpIds
.
contains
(
"5"
),
"子末工序应包含 J1 末工序(id=5)"
);
assertTrue
(
bom
.
childLastOpIds
.
contains
(
"7"
),
"子末工序应包含 J2 末工序(id=7)"
);
}
@Test
void
testToBomRelations_NoMaterialRequirements_Empty
()
{
List
<
BomRelation
>
boms
=
DataAdapter
.
toBomRelations
(
buildEntries
(
100
));
assertTrue
(
boms
.
isEmpty
(),
"无 materialRequirements 时 BOM 关系应为空"
);
}
@Test
void
testSolve_WithOpDefs_AllConstraintsSatisfied
()
{
// ---- 1. 设备 ----
List
<
ResourceDef
>
resources
=
Arrays
.
asList
(
new
ResourceDef
(
"M0"
,
500
),
new
ResourceDef
(
"M1"
,
500
),
new
ResourceDef
(
"M2"
,
500
)
);
// ---- 2. 工序(FJSP:多设备可选)----
// unplannedCost 设高值,确保求解器强制所有工序规划(便于验证各约束)
List
<
OpDef
>
ops
=
new
ArrayList
<>();
ops
.
add
(
OpDef
.
builder
(
"J0_O0"
,
"成品-工序0"
)
.
addResource
(
"M0"
,
12
).
addResource
(
"M1"
,
10
)
.
earliestStart
(
0
).
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J0_O1"
,
"成品-工序1"
)
.
addResource
(
"M1"
,
14
).
addResource
(
"M2"
,
15
)
.
predecessor
(
"J0_O0"
)
.
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J0_O2"
,
"成品-工序2"
)
.
addResource
(
"M0"
,
8
).
addResource
(
"M2"
,
11
)
.
predecessor
(
"J0_O1"
)
.
outputQty
(
1
,
"FG"
)
// 成品产出,用于库存约束
.
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J1_O0"
,
"半A-工序0"
)
.
addResource
(
"M0"
,
8
).
addResource
(
"M2"
,
9
)
.
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J1_O1"
,
"半A-工序1"
)
.
addResource
(
"M1"
,
11
)
.
predecessor
(
"J1_O0"
)
.
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J2_O0"
,
"半B-工序0"
)
.
addResource
(
"M1"
,
7
).
addResource
(
"M2"
,
10
)
.
unplannedCost
(
100000
)
.
build
());
ops
.
add
(
OpDef
.
builder
(
"J2_O1"
,
"半B-工序1"
)
.
addResource
(
"M0"
,
13
).
addResource
(
"M1"
,
9
)
.
predecessor
(
"J2_O0"
)
.
latestEnd
(
60
)
// 时间窗软约束:最晚 60 时刻完工
.
unplannedCost
(
100000
)
.
build
());
// ---- 3. BOM 齐套:成品首工序 ≥ 半成品末工序 ----
List
<
BomRelation
>
bom
=
Arrays
.
asList
(
new
BomRelation
(
"J0_O0"
,
Arrays
.
asList
(
"J1_O1"
,
"J2_O1"
))
);
// ---- 4. 换型矩阵 ----
Map
<
String
,
Double
>
setupM0
=
new
HashMap
<>();
setupM0
.
put
(
"J0_O0|J2_O1"
,
3.0
);
setupM0
.
put
(
"J2_O1|J0_O0"
,
3.0
);
setupM0
.
put
(
"J0_O2|J1_O0"
,
2.0
);
Map
<
String
,
Double
>
setupM1
=
new
HashMap
<>();
setupM1
.
put
(
"J0_O0|J0_O1"
,
4.0
);
setupM1
.
put
(
"J1_O1|J0_O1"
,
2.0
);
List
<
SetupMatrix
>
setups
=
Arrays
.
asList
(
new
SetupMatrix
(
"M0"
,
setupM0
),
new
SetupMatrix
(
"M1"
,
setupM1
)
);
// ---- 5. 库存约束(软约束)----
List
<
InventoryConstraint
>
inv
=
Arrays
.
asList
(
new
InventoryConstraint
(
"FG"
,
100
,
0
,
1000
,
false
)
);
// ---- 6. 配置 ----
ModelConfig
cfg
=
new
ModelConfig
();
cfg
.
timeLimitSeconds
=
10
;
cfg
.
weightMakespan
=
1.0
;
cfg
.
weightUnplanned
=
1000.0
;
cfg
.
weightLatestEndViol
=
500.0
;
// ---- 7. 构建并求解 ----
POAOrToolsModel
scheduler
=
new
POAOrToolsModel
(
ops
,
resources
,
bom
,
setups
,
inv
,
cfg
);
scheduler
.
build
();
SolveResult
result
=
scheduler
.
solve
();
printResult
(
result
);
// ---- 8. 断言 ----
assertTrue
(
result
.
isFeasible
,
"模型应可行"
);
assertTrue
(
result
.
makespan
>
0
,
"makespan 应大于 0"
);
// 未规划惩罚权重高,7 道工序均应被规划
assertTrue
(
result
.
unscheduledOps
.
isEmpty
(),
"所有工序均应被规划,实际未规划: "
+
result
.
unscheduledOps
);
assertEquals
(
7
,
result
.
startTimes
.
size
(),
"应规划 7 道工序"
);
// 前序约束:end(prev) <= start(curr)
assertOrder
(
"J0_O0"
,
"J0_O1"
,
result
);
assertOrder
(
"J0_O1"
,
"J0_O2"
,
result
);
assertOrder
(
"J1_O0"
,
"J1_O1"
,
result
);
assertOrder
(
"J2_O0"
,
"J2_O1"
,
result
);
// BOM 齐套:父首工序 start >= max(子末工序 end)
assertTrue
(
result
.
startTimes
.
get
(
"J0_O0"
)
>=
Math
.
max
(
result
.
endTimes
.
get
(
"J1_O1"
),
result
.
endTimes
.
get
(
"J2_O1"
))
-
1
e
-
6
,
"BOM 齐套约束应满足"
);
// 时间窗软约束:J2_O1 最晚完工 60(允许极小容差)
assertTrue
(
result
.
endTimes
.
get
(
"J2_O1"
)
<=
60
+
1
e
-
6
,
"J2_O1 应满足最晚完工时间窗"
);
}
private
void
assertOrder
(
String
prevOp
,
String
currOp
,
SolveResult
r
)
{
assertTrue
(
r
.
endTimes
.
get
(
prevOp
)
<=
r
.
startTimes
.
get
(
currOp
)
+
1
e
-
6
,
prevOp
+
" 应早于 "
+
currOp
+
" 完成"
);
}
/**
* 构建 3 个工单(J0 成品 + J1/J2 半成品)共 7 道工序的 Entry 列表。
* 工序ID: 1-7;前序依赖通过 prevEntryIds 设置。
*/
private
List
<
Entry
>
buildEntries
(
double
priority
)
{
List
<
Entry
>
entries
=
new
ArrayList
<>();
entries
.
add
(
op
(
1
,
"J0"
,
1
,
"成品-工序0"
,
priority
,
opt
(
0L
,
12
),
opt
(
1L
,
10
)));
entries
.
add
(
op
(
2
,
"J0"
,
2
,
"成品-工序1"
,
priority
,
opt
(
1L
,
14
),
opt
(
2L
,
15
)));
entries
.
add
(
op
(
3
,
"J0"
,
3
,
"成品-工序2"
,
priority
,
opt
(
0L
,
8
),
opt
(
2L
,
11
)));
entries
.
add
(
op
(
4
,
"J1"
,
1
,
"半A-工序0"
,
priority
,
opt
(
0L
,
8
),
opt
(
2L
,
9
)));
entries
.
add
(
op
(
5
,
"J1"
,
2
,
"半A-工序1"
,
priority
,
opt
(
1L
,
11
)));
entries
.
add
(
op
(
6
,
"J2"
,
1
,
"半B-工序0"
,
priority
,
opt
(
1L
,
7
),
opt
(
2L
,
10
)));
entries
.
add
(
op
(
7
,
"J2"
,
2
,
"半B-工序1"
,
priority
,
opt
(
0L
,
13
),
opt
(
1L
,
9
)));
dep
(
entries
.
get
(
1
),
entries
.
get
(
0
));
// J0_O1 依赖 J0_O0
dep
(
entries
.
get
(
2
),
entries
.
get
(
1
));
// J0_O2 依赖 J0_O1
dep
(
entries
.
get
(
4
),
entries
.
get
(
3
));
// J1_O1 依赖 J1_O0
dep
(
entries
.
get
(
6
),
entries
.
get
(
5
));
// J2_O1 依赖 J2_O0
return
entries
;
}
private
Entry
op
(
int
id
,
String
orderId
,
int
sequence
,
String
name
,
double
priority
,
MachineOption
...
opts
)
{
Entry
e
=
new
Entry
();
e
.
setId
(
id
);
e
.
setOrderId
(
orderId
);
e
.
setSequence
(
sequence
);
e
.
setRoutingDetailName
(
name
);
e
.
setPriority
(
priority
);
e
.
setMachineOptions
(
Arrays
.
asList
(
opts
));
return
e
;
}
private
MachineOption
opt
(
Long
machineId
,
double
processingTime
)
{
MachineOption
mo
=
new
MachineOption
();
mo
.
setMachineId
(
machineId
);
mo
.
setProcessingTime
(
processingTime
);
return
mo
;
}
private
void
dep
(
Entry
entry
,
Entry
prev
)
{
OperationDependency
d
=
new
OperationDependency
();
d
.
setPrevOperationId
(
prev
.
getId
());
entry
.
getPrevEntryIds
().
add
(
d
);
}
/** BOM 物料需求:childOrderId 指向子工单 */
private
OrderMaterialRequirement
bomReq
(
String
childOrderId
)
{
OrderMaterialRequirement
omr
=
new
OrderMaterialRequirement
();
omr
.
setChildOrderId
(
childOrderId
);
return
omr
;
}
/** BOM 物料需求:childOrderId 指向子工单 + 消耗数量 */
private
OrderMaterialRequirement
bomReq
(
String
childOrderId
,
double
qty
)
{
OrderMaterialRequirement
omr
=
bomReq
(
childOrderId
);
omr
.
setRequiredQuantity
(
qty
);
return
omr
;
}
/** 设置工序的物料需求(BOM + 库存消耗) */
private
Entry
setMr
(
Entry
e
,
OrderMaterialRequirement
...
reqs
)
{
e
.
setMaterialRequirements
(
Arrays
.
asList
(
reqs
));
return
e
;
}
/** 设置工序的产品产出(库存产出) */
private
Entry
setProduct
(
Entry
e
,
String
productId
,
double
qty
)
{
e
.
setProductId
(
productId
);
e
.
setQuantity
(
qty
);
return
e
;
}
private
void
printResult
(
SolveResult
result
)
{
System
.
out
.
println
(
"\n========== 排产结果 =========="
);
System
.
out
.
println
(
result
);
System
.
out
.
println
(
"工序明细:"
);
List
<
Map
.
Entry
<
String
,
Double
>>
sorted
=
new
ArrayList
<>(
result
.
startTimes
.
entrySet
());
sorted
.
sort
(
Map
.
Entry
.
comparingByValue
());
for
(
Map
.
Entry
<
String
,
Double
>
e
:
sorted
)
{
String
opId
=
e
.
getKey
();
System
.
out
.
printf
(
" %-8s → %s | start=%.1f, end=%.1f, dur=%.1f%n"
,
opId
,
result
.
assignedResource
.
get
(
opId
),
e
.
getValue
(),
result
.
endTimes
.
get
(
opId
),
result
.
endTimes
.
get
(
opId
)
-
e
.
getValue
());
}
if
(!
result
.
unscheduledOps
.
isEmpty
())
{
System
.
out
.
println
(
"未规划工序:"
+
result
.
unscheduledOps
);
}
}
}
src/test/java/com/aps/demo/POAOrToolsModelTestRunner.java
0 → 100644
View file @
1ade661a
package
com
.
aps
.
demo
;
/**
* POAOrToolsModelTest 的独立运行入口(不依赖 JUnit 引擎 / maven surefire)。
*
* 运行方式(本项目根目录):
* javac -encoding UTF-8 -d target\demo-test-classes -cp <依赖classpath> ^
* src\main\java\com\aps\poa\model\POAOrToolsModel.java ^
* src\test\java\com\aps\demo\POAOrToolsModelTest.java ^
* src\test\java\com\aps\demo\POAOrToolsModelTestRunner.java
* java -cp <classpath> com.aps.demo.POAOrToolsModelTestRunner
*/
public
class
POAOrToolsModelTestRunner
{
public
static
void
main
(
String
[]
args
)
{
try
{
POAOrToolsModelTest
.
init
();
POAOrToolsModelTest
test
=
new
POAOrToolsModelTest
();
test
.
testToOpDefs_EntryMapping
();
test
.
testToOpDefs_NoMachineOptions_Throws
();
test
.
testToOpDefs_MultiInputProducts
();
test
.
testToResourceDefs_MachineMapping
();
test
.
testToBomRelations_FromMaterialRequirements
();
test
.
testToBomRelations_NoMaterialRequirements_Empty
();
test
.
testSolve_WithBusinessEntities
();
test
.
testSolve_WithOpDefs_AllConstraintsSatisfied
();
System
.
out
.
println
(
"\n[TEST PASS] 全部 8 个用例通过"
);
}
catch
(
Throwable
t
)
{
System
.
err
.
println
(
"\n[TEST FAIL] "
+
t
);
t
.
printStackTrace
(
System
.
err
);
System
.
exit
(
1
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment